|
3 | 3 |
|
4 | 4 | using System; |
5 | 5 | using System.Collections.Generic; |
| 6 | +using System.Diagnostics; |
6 | 7 | using System.Linq; |
7 | 8 | using System.Threading; |
8 | 9 | using System.Threading.Tasks; |
@@ -102,6 +103,8 @@ private async Task processUser(MySqlConnection db, int userId, CancellationToken |
102 | 103 | continue; |
103 | 104 | } |
104 | 105 |
|
| 106 | + Debug.Assert(preservedAlternatives.Count > 0); |
| 107 | + |
105 | 108 | if (Verbose) |
106 | 109 | { |
107 | 110 | formatOutput(score, true, "superseded"); |
@@ -145,25 +148,35 @@ private async Task<bool> checkIsMultiplayerScoreAsync(MySqlConnection db, SoloSc |
145 | 148 |
|
146 | 149 | private static bool checkIsUserHigh(IEnumerable<SoloScore> userScores, SoloScore candidate, out HashSet<SoloScore> preservedAlternatives) |
147 | 150 | { |
148 | | - userScores = userScores.Where(s => |
| 151 | + var scores = userScores.Where(s => |
149 | 152 | s.beatmap_id == candidate.beatmap_id |
150 | 153 | && s.ruleset_id == candidate.ruleset_id |
151 | 154 | && compareMods(candidate, s) |
152 | 155 | && s.ranked |
153 | | - ); |
| 156 | + ).ToArray(); |
| 157 | + |
| 158 | + // As a special case, if the score we are checking is non-ranked, preserve ranked alternatives but if there are none, compare against non-ranked instead. |
| 159 | + if (!candidate.ranked && scores.Length == 0) |
| 160 | + { |
| 161 | + scores = userScores.Where(s => |
| 162 | + s.beatmap_id == candidate.beatmap_id |
| 163 | + && s.ruleset_id == candidate.ruleset_id |
| 164 | + && compareMods(candidate, s) |
| 165 | + ).ToArray(); |
| 166 | + } |
154 | 167 |
|
155 | 168 | preservedAlternatives = new HashSet<SoloScore>(); |
156 | 169 |
|
157 | 170 | // TODO: this can likely be optimised (to not recalculate every score, in the case there's many candidates per beatmap). |
158 | | - if (userScores.MaxBy(s => s.pp) is SoloScore maxPPScore) |
| 171 | + if (scores.MaxBy(s => s.pp) is SoloScore maxPPScore) |
159 | 172 | preservedAlternatives.Add(maxPPScore); |
160 | | - if (userScores.Where(s => s.legacy_total_score == 0).MaxBy(s => s.total_score) is SoloScore maxTotalScoreLazer) |
| 173 | + if (scores.Where(s => s.legacy_total_score == 0).MaxBy(s => s.total_score) is SoloScore maxTotalScoreLazer) |
161 | 174 | preservedAlternatives.Add(maxTotalScoreLazer); |
162 | 175 | // i'm not sure that we need this one but for now let's play it safe and not nuke scores users may care about. |
163 | | - if (userScores.Where(s => s.legacy_total_score > 0).MaxBy(s => s.legacy_total_score) is SoloScore maxTotalScoreStable) |
| 176 | + if (scores.Where(s => s.legacy_total_score > 0).MaxBy(s => s.legacy_total_score) is SoloScore maxTotalScoreStable) |
164 | 177 | preservedAlternatives.Add(maxTotalScoreStable); |
165 | 178 | // there's a very high possibility that this one is either `maxTotalScoreLazer` or `maxTotalScoreStable`, but just to be 100% sure... |
166 | | - if (userScores.MaxBy(s => s.total_score) is SoloScore maxTotalScore) |
| 179 | + if (scores.MaxBy(s => s.total_score) is SoloScore maxTotalScore) |
167 | 180 | preservedAlternatives.Add(maxTotalScore); |
168 | 181 |
|
169 | 182 | // Check whether this score is the user's highest |
|
0 commit comments