using ReactiveUI; using ReactiveUI.Fody.Helpers; using Splat; using System.Reactive; namespace ServiceLib.ViewModels { public class BackupAndRestoreViewModel : MyReactiveObject { private readonly string _guiConfigs = "guiConfigs"; private static string BackupFileName => $"backup_{DateTime.Now:yyyyMMddHHmmss}.zip"; public ReactiveCommand RemoteBackupCmd { get; } public ReactiveCommand RemoteRestoreCmd { get; } public ReactiveCommand WebDavCheckCmd { get; } [Reactive] public WebDavItem SelectedSource { get; set; } [Reactive] public string OperationMsg { get; set; } public BackupAndRestoreViewModel(Func>? updateView) { _config = LazyConfig.Instance.Config; _updateView = updateView; _noticeHandler = Locator.Current.GetService(); WebDavCheckCmd = ReactiveCommand.CreateFromTask(async () => { await WebDavCheck(); }); RemoteBackupCmd = ReactiveCommand.CreateFromTask(async () => { await RemoteBackup(); }); RemoteRestoreCmd = ReactiveCommand.CreateFromTask(async () => { await RemoteRestore(); }); SelectedSource = JsonUtils.DeepCopy(_config.webDavItem); } private void DisplayOperationMsg(string msg = "") { OperationMsg = msg; } private async Task WebDavCheck() { DisplayOperationMsg(); _config.webDavItem = SelectedSource; ConfigHandler.SaveConfig(_config); var result = await WebDavHandler.Instance.CheckConnection(); if (result) { DisplayOperationMsg(ResUI.OperationSuccess); } else { DisplayOperationMsg(WebDavHandler.Instance.GetLastError()); } } private async Task RemoteBackup() { DisplayOperationMsg(); var fileName = Utils.GetBackupPath(BackupFileName); var result = await CreateZipFileFromDirectory(fileName); if (result) { var result2 = await WebDavHandler.Instance.PutFile(fileName); if (result2) { DisplayOperationMsg(ResUI.OperationSuccess); return; } } DisplayOperationMsg(WebDavHandler.Instance.GetLastError()); } private async Task RemoteRestore() { DisplayOperationMsg(); var fileName = Utils.GetTempPath(Utils.GetGUID()); var result = await WebDavHandler.Instance.GetRawFile(fileName); if (result) { await LocalRestore(fileName); return; } DisplayOperationMsg(WebDavHandler.Instance.GetLastError()); } public async Task LocalBackup(string fileName) { DisplayOperationMsg(); var result = await CreateZipFileFromDirectory(fileName); if (result) { DisplayOperationMsg(ResUI.OperationSuccess); } else { DisplayOperationMsg(WebDavHandler.Instance.GetLastError()); } return result; } public async Task LocalRestore(string fileName) { DisplayOperationMsg(); if (Utils.IsNullOrEmpty(fileName)) { return; } //exist if (!File.Exists(fileName)) { 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(BackupFileName); var result = await CreateZipFileFromDirectory(fileBackup); if (result) { Locator.Current.GetService()?.V2rayUpgrade(fileName); } else { DisplayOperationMsg(WebDavHandler.Instance.GetLastError()); } } private async Task CreateZipFileFromDirectory(string fileName) { if (Utils.IsNullOrEmpty(fileName)) { return false; } var configDir = Utils.GetConfigPath(); var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}"); 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)); await Task.Run(() => Directory.Delete(configDirZipTemp, true)); return ret; } } }