using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Data; using System.Windows.Input; using System.Windows.Threading; using Crysome.Common.Model; using Crysome.Common.Network.Packets; using Crysome.Common.Network.Packets.Client; using Crysome.Common.Network.Packets.Server; using Crysome.Server.Model; using Crysome.Server.Network; using Microsoft.Win32; namespace Crysome.Server.ViewModel; public class FileExplorerViewModel : ViewModelBase, IDisposable { private bool _downloadProgressVisible; private string _downloadStatusText; private double _downloadProgress; private string _pendingDownloadSavePath; private Stopwatch _downloadStopwatch; private readonly MainViewModel _mainVm; private bool _disposed; private string[] _drives; private FileSystemEntry _currentDirectory; private FileSystemEntry _selectedFile; private string _sortMode = "Name"; public bool DownloadProgressVisible { get { return _downloadProgressVisible; } set { _downloadProgressVisible = value; OnPropertyChanged(() => DownloadProgressVisible); } } public string DownloadStatusText { get { return _downloadStatusText; } set { _downloadStatusText = value; OnPropertyChanged(() => DownloadStatusText); } } public double DownloadProgress { get { return _downloadProgress; } set { _downloadProgress = value; OnPropertyChanged(() => DownloadProgress); } } public ObservableCollection Files { get; set; } public ICollectionView FilesView { get; private set; } public Stack BackHistory { get; set; } public Stack ForwardHistory { get; set; } public bool CanGoBackward => BackHistory.Count > 0; public bool CanGoForward => ForwardHistory.Count > 0; public string[] Drives { get { return _drives; } set { _drives = value; OnPropertyChanged(() => Drives); } } public FileSystemEntry CurrentDirectory { get { return _currentDirectory; } set { _currentDirectory = value; OnPropertyChanged(() => CurrentDirectory); } } public FileSystemEntry SelectedFile { get { return _selectedFile; } set { _selectedFile = value; OnPropertyChanged(() => _selectedFile); } } public string SortMode { get { return _sortMode; } set { _sortMode = value ?? "Name"; OnPropertyChanged(() => SortMode); ApplySort(); } } public string[] SortOptions { get; } = new string[4] { "Name", "DateModified", "Size", "Type" }; public ICommand NavigateCommand { get; set; } public ICommand NavigateSelectedCommand { get; set; } public ICommand OpenCommand { get; set; } public ICommand SaveAsCommand { get; set; } public ICommand UploadCommand { get; set; } public ICommand PropertiesCommand { get; set; } public ICommand NavigateUpCommand { get; set; } public ICommand NavigateForwardCommand { get; set; } public ICommand NavigateBackCommand { get; set; } public ICommand DeleteFileCommand { get; set; } public ClientInfo Client { get; set; } public ICommand GoBackToClientsCommand { get; set; } public FileExplorerViewModel(CrysomeServer server, ClientInfo client, MainViewModel mainVm) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown FileExplorerViewModel fileExplorerViewModel = this; _mainVm = mainVm; Files = new ObservableCollection(); FilesView = CollectionViewSource.GetDefaultView(Files); ApplySort(); BackHistory = new Stack(); ForwardHistory = new Stack(); Client = client; _mainVm.ClientsVM.RegisterActiveFileExplorer(client.Owner, this); if (server.ClientCount > 0) { long num = _mainVm.ClientsVM.NextExplorerOpId(); _mainVm.ClientsVM.RegisterGetDirectoryCallback(client.Owner, num, delegate(GetDirectoryResponsePacket p) { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { fileExplorerViewModel.ApplyGetDirectoryResponse(p); }); }); client.Owner.SendPacket((IPacket)new GetDirectoryRequestPacket(string.Empty, num)); long requestId = _mainVm.ClientsVM.NextExplorerOpId(); _mainVm.ClientsVM.RegisterGetDrivesCallback(client.Owner, requestId, delegate(GetDrivesResponsePacket p) { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { fileExplorerViewModel.ApplyGetDrivesResponse(p); }); }); client.Owner.SendPacket((IPacket)new GetDrivesRequestPacket { RequestId = requestId }); } NavigateCommand = new RelayCommand(NavigateWithHistory); NavigateSelectedCommand = new RelayCommand(NavigateSelected); OpenCommand = new RelayCommand(OpenSelected); SaveAsCommand = new RelayCommand(SaveAsSelected); UploadCommand = new RelayCommand(delegate { fileExplorerViewModel.UploadFile(); }); PropertiesCommand = new RelayCommand(ShowProperties); NavigateUpCommand = new RelayCommand(NavigateUp); NavigateForwardCommand = new RelayCommand(NavigateForward); NavigateBackCommand = new RelayCommand(NavigateBack); DeleteFileCommand = new RelayCommand(DeleteFile); GoBackToClientsCommand = new RelayCommand(delegate { mainVm.GoToClients(); }); } public void Dispose() { if (!_disposed) { _disposed = true; if (Client?.Owner != null) { _mainVm.ClientsVM.UnregisterActiveFileExplorer(Client.Owner, this); } } } private void ApplySort() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (FilesView == null) { return; } using (FilesView.DeferRefresh()) { ((Collection)(object)FilesView.SortDescriptions).Clear(); switch (SortMode) { case "DateModified": ((Collection)(object)FilesView.SortDescriptions).Add(new SortDescription("LastWriteUtcTicks", ListSortDirection.Descending)); break; case "Size": ((Collection)(object)FilesView.SortDescriptions).Add(new SortDescription("Size", ListSortDirection.Descending)); break; case "Type": ((Collection)(object)FilesView.SortDescriptions).Add(new SortDescription("Type", ListSortDirection.Ascending)); ((Collection)(object)FilesView.SortDescriptions).Add(new SortDescription("Name", ListSortDirection.Ascending)); break; default: ((Collection)(object)FilesView.SortDescriptions).Add(new SortDescription("Name", ListSortDirection.Ascending)); break; } } } public void ApplyGetDirectoryResponse(GetDirectoryResponsePacket directoryResponse) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown Files.Clear(); CurrentDirectory = new FileSystemEntry(directoryResponse.Name, directoryResponse.Path, 0L, (FileType)0, 0L, (byte[])null); OnPropertyChanged(() => CanGoBackward); OnPropertyChanged(() => CanGoForward); string[] folders = directoryResponse.Folders; int num = ((folders != null) ? folders.Length : 0); long[] folderLastWriteUtcTicks = directoryResponse.FolderLastWriteUtcTicks; byte[][] folderIconPng = directoryResponse.FolderIconPng; for (int num2 = 0; num2 < num; num2++) { long num3 = ((folderLastWriteUtcTicks != null && num2 < folderLastWriteUtcTicks.Length) ? folderLastWriteUtcTicks[num2] : 0); byte[] array = ((folderIconPng != null && num2 < folderIconPng.Length) ? folderIconPng[num2] : null); Files.Add(new FileSystemEntry(directoryResponse.Folders[num2], Path.Combine(CurrentDirectory.Path, directoryResponse.Folders[num2]), 0L, (FileType)0, num3, array)); } string[] files = directoryResponse.Files; int num4 = ((files != null) ? files.Length : 0); long[] fileLastWriteUtcTicks = directoryResponse.FileLastWriteUtcTicks; byte[][] fileIconPng = directoryResponse.FileIconPng; for (int num5 = 0; num5 < num4; num5++) { long num6 = ((fileLastWriteUtcTicks != null && num5 < fileLastWriteUtcTicks.Length) ? fileLastWriteUtcTicks[num5] : 0); byte[] array2 = ((fileIconPng != null && num5 < fileIconPng.Length) ? fileIconPng[num5] : null); Files.Add(new FileSystemEntry(directoryResponse.Files[num5], Path.Combine(CurrentDirectory.Path, directoryResponse.Files[num5]), directoryResponse.FileSizes[num5], (FileType)1, num6, array2)); } ApplySort(); } public void ApplyGetDrivesResponse(GetDrivesResponsePacket getDrivesPacket) { Drives = getDrivesPacket.Drives; } public void ApplyNotifyStatus(NotifyStatusResponsePacket statusPacket) { _mainVm.ClientsVM?.EnqueueStatus(statusPacket.StatusMessage); } private void Navigate(string path) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown long num = _mainVm.ClientsVM.NextExplorerOpId(); _mainVm.ClientsVM.RegisterGetDirectoryCallback(Client.Owner, num, delegate(GetDirectoryResponsePacket p) { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { ApplyGetDirectoryResponse(p); }); }); Client.Owner.SendPacket((IPacket)new GetDirectoryRequestPacket(path, num)); } private void NavigateWithHistory(string path) { if (CurrentDirectory != null && path != CurrentDirectory.Path) { BackHistory.Push(CurrentDirectory); } Navigate(path); } private void NavigateSelected(string s) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (SelectedFile != null && (int)SelectedFile.Type == 0) { NavigateWithHistory(SelectedFile.Path); } } private void NavigateUp(string s) { NavigateWithHistory(Path.Combine(CurrentDirectory.Path, "..")); } private void NavigateForward(string s) { BackHistory.Push(CurrentDirectory); FileSystemEntry val = ForwardHistory.Pop(); Navigate(val.Path); } private void NavigateBack(string s) { ForwardHistory.Push(CurrentDirectory); FileSystemEntry val = BackHistory.Pop(); Navigate(val.Path); } private void DeleteFile(string s) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (SelectedFile != null) { FileSystemEntry selectedFile = SelectedFile; if (MessageBox.Show("Delete " + selectedFile.Name + "?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { Client.Owner.SendPacket((IPacket)new DeleteFileRequestPacket(selectedFile.Path)); _mainVm.ClientsVM?.EnqueueStatus("Delete sent for " + selectedFile.Name); } } } private void OpenSelected(string s) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (SelectedFile != null && (int)SelectedFile.Type == 0) { NavigateWithHistory(SelectedFile.Path); } } private void SaveAsSelected(string s) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown if (SelectedFile == null) { return; } if ((int)SelectedFile.Type == 0) { _mainVm.ClientsVM?.EnqueueStatus("Select a file to download."); return; } SaveFileDialog saveFileDialog = new SaveFileDialog { FileName = SelectedFile.Name, Filter = "All files|*.*", DefaultExt = Path.GetExtension(SelectedFile.Name) }; if (saveFileDialog.ShowDialog() != true) { return; } string fileName = saveFileDialog.FileName; _pendingDownloadSavePath = fileName; DownloadProgressVisible = true; DownloadProgress = 0.0; DownloadStatusText = "Downloading..."; _downloadStopwatch = Stopwatch.StartNew(); long num = _mainVm.ClientsVM.NextExplorerOpId(); _mainVm.ClientsVM.RegisterReadFileCallback(Client.Owner, num, delegate(ReadFileResponsePacket resp) { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { CompleteDownloadSave(resp); }); }); Client.Owner.SendPacket((IPacket)new ReadFileRequestPacket(SelectedFile.Path, num)); } private void CompleteDownloadSave(ReadFileResponsePacket resp) { string pendingDownloadSavePath = _pendingDownloadSavePath; _pendingDownloadSavePath = null; try { if (resp.Success && resp.Data != null) { File.WriteAllBytes(pendingDownloadSavePath, resp.Data); TimeSpan timeSpan = _downloadStopwatch?.Elapsed ?? TimeSpan.Zero; _mainVm.ClientsVM?.EnqueueStatus($"Saved to {pendingDownloadSavePath} ({resp.Data.Length / 1024} KB in {timeSpan.TotalSeconds:F1}s)"); } else { _mainVm.ClientsVM?.EnqueueStatus("Download failed: " + (((resp != null) ? resp.ErrorMessage : null) ?? "Unknown error")); } } catch (Exception ex) { _mainVm.ClientsVM?.EnqueueStatus("Save failed: " + ex.Message); } DownloadProgressVisible = false; DownloadStatusText = ""; } private void UploadFile() { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown if (CurrentDirectory == null) { return; } OpenFileDialog openFileDialog = new OpenFileDialog { Filter = "All files|*.*" }; if (openFileDialog.ShowDialog() != true) { return; } byte[] array; try { array = File.ReadAllBytes(openFileDialog.FileName); } catch (Exception ex) { _mainVm.ClientsVM?.EnqueueStatus("Upload read error: " + ex.Message); return; } long num = (long)_mainVm.ClientsVM.Store.Settings.MaxSendFileSizeMB * 1024L * 1024; if (num > 0 && array.Length > num) { _mainVm.ClientsVM?.EnqueueStatus("File too large (limit " + _mainVm.ClientsVM.Store.Settings.MaxSendFileSizeMB + " MB)"); return; } string name = Path.GetFileName(openFileDialog.FileName); string destPath = Path.Combine(CurrentDirectory.Path, name); long transferId = _mainVm.ClientsVM.NextExplorerOpId(); DownloadProgressVisible = true; DownloadStatusText = "Uploading..."; _mainVm.ClientsVM.RegisterWriteFileCallback(Client.Owner, transferId, delegate(WriteFileResponsePacket resp) { ((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate { DownloadProgressVisible = false; DownloadStatusText = ""; if (resp.Success) { _mainVm.ClientsVM?.EnqueueStatus("Uploaded " + name); Navigate(CurrentDirectory.Path); } else { _mainVm.ClientsVM?.EnqueueStatus("Upload failed: " + (resp.ErrorMessage ?? "?")); } }); }); Client.Owner.SendPacket((IPacket)new WriteFileRequestPacket { DestPath = destPath, TransferId = transferId, Data = array }); } private void ShowProperties(string s) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (SelectedFile != null) { FileSystemEntry selectedFile = SelectedFile; string value = (((int)selectedFile.Type == 0) ? "—" : FormatFileSize(selectedFile.Size)); string value2 = ((selectedFile.LastWriteUtcTicks > 0) ? new DateTime(selectedFile.LastWriteUtcTicks, DateTimeKind.Utc).ToLocalTime().ToString("yyyy-MM-dd HH:mm") : "—"); MessageBox.Show($"Name: {selectedFile.Name}\nPath: {selectedFile.Path}\nType: {selectedFile.Type}\nSize: {value}\nModified: {value2}", "Properties", MessageBoxButton.OK, MessageBoxImage.Asterisk); } } private static string FormatFileSize(long bytes) { if (bytes < 1024) { return bytes + " B"; } if (bytes < 1048576) { return ((double)bytes / 1024.0).ToString("F1") + " KB"; } if (bytes < 1073741824) { return ((double)bytes / 1048576.0).ToString("F1") + " MB"; } return ((double)bytes / 1073741824.0).ToString("F1") + " GB"; } }