private void UpdateOnlinePlayers(object sender) { bool playerListChanged = false; var server = sender as Server; if (sender == null || !server.IsRconConnected || Rcon == null) { return; } var newList = Rcon.GetPlayerList().With(list => list.Where(p => p != null)); if (newList == null) { return; } if (newList.Count() == 0) { lock (server.lockOnlinePlayers) OnlinePlayers.Clear(); if (OnPlayerListChange != null) { OnPlayerListChange(OnlinePlayers.ToList(), this); } return; } HashSet <Guid> onlineIds = new HashSet <Guid> (newList.Select(player => player.NickId)); lock (server.lockOnlinePlayers) { playerListChanged = OnlinePlayers.Count(p => !onlineIds.Contains(p.NickId)) > 0; OnlinePlayers.RemoveAll(player => !onlineIds.Contains(player.NickId)); foreach (var player in newList) { var existing = OnlinePlayers.FirstOrDefault(p => p.NickId.Equals(player.NickId)); if (existing == null) { OnlinePlayers.Add(player); playerListChanged = true; } else { if (!playerListChanged) { playerListChanged = existing.Ping != player.Ping || existing.Status != player.Status || existing.CoalitionIndex != player.CoalitionIndex; } existing.Ping = player.Ping; existing.Status = player.Status; existing.ClientId = player.ClientId; existing.CoalitionIndex = player.CoalitionIndex; } } if (playerListChanged && OnPlayerListChange != null) { OnPlayerListChange(OnlinePlayers.ToList(), this); } } }