private static void doTeamMatchmake() { Random rnd = new Random(); Matchmake[] mmArray; //we can't lock the whole thing, will make scale a pain lock (inTeamMatchmaking) mmArray = inTeamMatchmaking.ToArray(); foreach (var match in mmArray) { lock (match) { //we do this cause the matchFound is still in the array. So we prevent matching it again if (match.Status == MatchmakeStatus.AlreadyMatched) { continue; } // Find match with a similar rating (search margin increases every try) and a common mod var matchFound = mmArray.FirstOrDefault(x => match.IsMatch(x, true)); if (matchFound != null) { //give priority to localized matches var region = ServerRegion.UNKNOWN; if (match.Region != ServerRegion.UNKNOWN) { region = match.Region; } else if (matchFound.Region != ServerRegion.UNKNOWN) { region = matchFound.Region; } //get available mods by rating var mods = match.GetMatchedMods(matchFound); //create a lobby with one of the mods var lobby = LobbyManager.CreateMatchedLobby(match, matchFound, mods[rnd.Next(0, mods.Length)], region); //remove the matchmake from the browsers and set the lobby foreach (var browser in Browsers.Find(b => b.user != null && b.matchmake != null && (b.matchmake.id == match.id || b.matchmake.id == matchFound.id))) { browser.matchmake = null; browser.lobby = lobby; browser.AsyncSend(BrowserController.LobbySnapshot(lobby), res => { }); } //prevent matches from matching again matchFound.Status = MatchmakeStatus.AlreadyMatched; match.Status = MatchmakeStatus.AlreadyMatched; //remove the matches from the queue lock (inTeamMatchmaking) { inTeamMatchmaking.Remove(match); inTeamMatchmaking.Remove(matchFound); } } else { match.TryCount++; } } } }