using ServerManagerTool.Common.Model; using ServerManagerTool.Common.Utils; using ServerManagerTool.Lib; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using WPFSharp.Globalizer; namespace ServerManagerTool { /// /// Interaction logic for WorldSaveRestoreWindow.xaml /// public partial class WorldSaveRestoreWindow : Window { public class WorldSaveFileList : SortableObservableCollection { public new void Add(WorldSaveFile item) { if (item == null || this.Any(m => m.FileName.Equals(item.FileName))) return; base.Add(item); } public override string ToString() { return $"{nameof(WorldSaveFile)} - {Count}"; } } public class WorldSaveFile : DependencyObject { public static readonly DependencyProperty CreatedDateProperty = DependencyProperty.Register(nameof(CreatedDate), typeof(DateTime), typeof(WorldSaveFile), new PropertyMetadata(DateTime.MinValue)); public static readonly DependencyProperty FileProperty = DependencyProperty.Register(nameof(File), typeof(string), typeof(WorldSaveFile), new PropertyMetadata(string.Empty)); public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register(nameof(FileName), typeof(string), typeof(WorldSaveFile), new PropertyMetadata(string.Empty)); public static readonly DependencyProperty UpdatedDateProperty = DependencyProperty.Register(nameof(UpdatedDate), typeof(DateTime), typeof(WorldSaveFile), new PropertyMetadata(DateTime.MinValue)); public static readonly DependencyProperty IsActiveFileProperty = DependencyProperty.Register(nameof(IsActiveFile), typeof(bool), typeof(WorldSaveFile), new PropertyMetadata(false)); public static readonly DependencyProperty IsArchiveFileProperty = DependencyProperty.Register(nameof(IsArchiveFile), typeof(bool), typeof(WorldSaveFile), new PropertyMetadata(false)); public DateTime CreatedDate { get { return (DateTime)GetValue(CreatedDateProperty); } set { SetValue(CreatedDateProperty, value); } } public string File { get { return (string)GetValue(FileProperty); } set { SetValue(FileProperty, value); } } public string FileName { get { return (string)GetValue(FileNameProperty); } set { SetValue(FileNameProperty, value); } } public DateTime UpdatedDate { get { return (DateTime)GetValue(UpdatedDateProperty); } set { SetValue(UpdatedDateProperty, value); } } public bool IsActiveFile { get { return (bool)GetValue(IsActiveFileProperty); } set { SetValue(IsActiveFileProperty, value); } } public bool IsArchiveFile { get { return (bool)GetValue(IsArchiveFileProperty); } set { SetValue(IsArchiveFileProperty, value); } } public override string ToString() { return FileName; } } public class WorldSaveFileComparer : IComparer { public int Compare(WorldSaveFile x, WorldSaveFile y) { if (x == null && y == null) return 0; if (x == null) return 1; if (y == null) return -1; if (x.IsActiveFile && y.IsActiveFile) { if (x.UpdatedDate == y.UpdatedDate) return 0; return x.UpdatedDate < y.UpdatedDate ? 1 : -1; } if (x.IsActiveFile) return -1; if (y.IsActiveFile) return 1; if (x.UpdatedDate == y.UpdatedDate) return 0; return x.UpdatedDate < y.UpdatedDate ? 1 : -1; } } private readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance; private readonly ServerProfile _profile = null; public static readonly DependencyProperty WorldSaveFilesProperty = DependencyProperty.Register(nameof(WorldSaveFiles), typeof(WorldSaveFileList), typeof(WorldSaveRestoreWindow), new PropertyMetadata(null)); public WorldSaveRestoreWindow(ServerProfile profile) { InitializeComponent(); WindowUtils.RemoveDefaultResourceDictionary(this, Config.Default.DefaultGlobalizationFile); _profile = profile; this.Title = string.Format(_globalizer.GetResourceString("WorldSaveRestore_ProfileTitle"), _profile?.ProfileName); WorldSaveFiles = new WorldSaveFileList(); this.DataContext = this; } public WorldSaveFileList WorldSaveFiles { get { return GetValue(WorldSaveFilesProperty) as WorldSaveFileList; } set { SetValue(WorldSaveFilesProperty, value); } } private async void Window_Loaded(object sender, RoutedEventArgs e) { try { await LoadWorldSaveFiles(); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("WorldSaveRestore_Load_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } } private async void Delete_Click(object sender, RoutedEventArgs e) { var item = ((WorldSaveFile)((Button)e.Source).DataContext); if (item == null) return; var deleteMessage = _globalizer.GetResourceString("WorldSaveRestore_DeleteConfirmationLabel"); deleteMessage = deleteMessage.Replace("{fileName}", item.FileName); if (MessageBox.Show(this, deleteMessage, _globalizer.GetResourceString("WorldSaveRestore_DeleteConfirmationTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = System.Windows.Input.Cursors.Wait); await Task.Delay(500); File.Delete(item.File); MessageBox.Show(this, _globalizer.GetResourceString("WorldSaveRestore_DeleteSuccessLabel"), _globalizer.GetResourceString("WorldSaveRestore_DeleteSuccessTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(this, ex.Message, _globalizer.GetResourceString("WorldSaveRestore_DeleteErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { await LoadWorldSaveFiles(); Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async void Reload_Click(object sender, RoutedEventArgs e) { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = System.Windows.Input.Cursors.Wait); await Task.Delay(500); await LoadWorldSaveFiles(); } catch (Exception ex) { MessageBox.Show(ex.Message, _globalizer.GetResourceString("WorldSaveRestore_Refresh_FailedTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async void Restore_Click(object sender, RoutedEventArgs e) { var item = ((WorldSaveFile)((Button)e.Source).DataContext); if (item == null) return; var restoreAll = true; if (item.IsArchiveFile) { var confirmationMessage = _globalizer.GetResourceString("WorldSaveRestore_RestoreConfirmationFullLabel"); confirmationMessage = confirmationMessage.Replace("{fileName}", item.FileName); var result = MessageBox.Show(this, confirmationMessage, _globalizer.GetResourceString("WorldSaveRestore_RestoreConfirmationTitle"), MessageBoxButton.YesNoCancel, MessageBoxImage.Question); if (result == MessageBoxResult.Cancel) return; restoreAll = result == MessageBoxResult.Yes; } else { var confirmationMessage = _globalizer.GetResourceString("WorldSaveRestore_RestoreConfirmationLabel"); confirmationMessage = confirmationMessage.Replace("{fileName}", item.FileName); if (MessageBox.Show(this, confirmationMessage, _globalizer.GetResourceString("WorldSaveRestore_RestoreConfirmationTitle"), MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; } var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = System.Windows.Input.Cursors.Wait); await Task.Delay(500); var restoredFileCount = _profile.RestoreSaveFiles(item.File, item.IsArchiveFile, restoreAll); var successMessage = _globalizer.GetResourceString("WorldSaveRestore_RestoreSuccessLabel"); successMessage = successMessage.Replace("{fileCount}", restoredFileCount.ToString()); MessageBox.Show(this, successMessage, _globalizer.GetResourceString("WorldSaveRestore_RestoreSuccessTitle"), MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show(this, ex.Message, _globalizer.GetResourceString("WorldSaveRestore_RestoreErrorTitle"), MessageBoxButton.OK, MessageBoxImage.Error); } finally { await LoadWorldSaveFiles(); Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } private async Task LoadWorldSaveFiles() { var cursor = this.Cursor; try { Application.Current.Dispatcher.Invoke(() => this.Cursor = System.Windows.Input.Cursors.Wait); await Task.Delay(500); WorldSaveFiles.Clear(); var saveFolder = ServerProfile.GetProfileSavePath(_profile); if (!Directory.Exists(saveFolder)) return; var saveFolderInfo = new DirectoryInfo(saveFolder); var mapName = ServerProfile.GetProfileMapFileName(_profile); var mapFileName = $"{mapName}{Config.Default.MapExtension}"; var searchPattern = $"{mapName}*{Config.Default.MapExtension}"; var saveFiles = saveFolderInfo.GetFiles(searchPattern); foreach (var file in saveFiles) { WorldSaveFiles.Add(new WorldSaveFile { File = file.FullName , FileName = file.Name, CreatedDate = file.CreationTime, UpdatedDate = file.LastWriteTime, IsArchiveFile = false, IsActiveFile = file.Name.Equals(mapFileName, StringComparison.OrdinalIgnoreCase) }); } var backupFolder = ServerApp.GetServerBackupFolder(_profile); if (Directory.Exists(backupFolder)) { var backupFolderInfo = new DirectoryInfo(backupFolder); searchPattern = $"{mapName}*{Config.Default.BackupExtension}"; var backupFiles = backupFolderInfo.GetFiles(searchPattern); foreach (var file in backupFiles) { WorldSaveFiles.Add(new WorldSaveFile { File = file.FullName, FileName = file.Name, CreatedDate = file.CreationTime, UpdatedDate = file.LastWriteTime, IsArchiveFile = true, IsActiveFile = false }); } } WorldSaveFiles.Sort(f => f, new WorldSaveFileComparer()); } finally { Application.Current.Dispatcher.Invoke(() => this.Cursor = cursor); } } } }