@@ -155,7 +155,7 @@ public DatabaseScoreList GetLevelTopScoresByFriends(GameUser user, GameLevel lev
155155
156156 /// <param name="scoreType">0 = don't filter by type</param>
157157 /// <param name="rank">0 = show all high-scores regardless of rank</param>
158- public DatabaseList < ScoreWithRank > GetScoresByUser ( GameUser user , int skip , int count , byte scoreType , int rank )
158+ public DatabaseList < ScoreWithRank > GetHighScoresByUser ( GameUser user , int skip , int count , byte scoreType , int rank )
159159 {
160160 IQueryable < GameScore > scores = this . GameScoresIncluded
161161 . Where ( s => s . PublisherId == user . UserId )
@@ -192,35 +192,35 @@ public void DeleteScore(GameScore score)
192192 IQueryable < Event > scoreEvents = this . Events
193193 . Where ( e => e . StoredDataType == EventDataType . Score && e . StoredObjectId == score . ScoreId ) ;
194194
195- this . Write ( ( ) =>
196- {
197- this . Events . RemoveRange ( scoreEvents ) ;
198- this . GameScores . Remove ( score ) ;
199- } ) ;
195+ this . Events . RemoveRange ( scoreEvents ) ;
196+ this . GameScores . Remove ( score ) ;
197+ this . SaveChanges ( ) ;
198+
199+ // Only recalculate ranks if the score was a high-score.
200+ // Also, separate write transaction because otherwise recalculation would still include the unwanted scores.
201+ if ( score . Rank != 0 )
202+ this . RecalculateScoreStatistics ( score . LevelId , score . ScoreType , true ) ;
200203 }
201204
202205 public void DeleteScoresSetByUser ( GameUser user )
203206 {
207+ // Find out which leaderboards we will have to recalculate the ranks of.
208+ // Only need high-scores for this, as the other, overtaken scores should not affect ranking at all,
209+ // and additionally, this way we will always have not more than 1 score per level/score type,
210+ // avoiding recalculation of the same leaderboards multiple times.
204211 IEnumerable < GameScore > scores = this . GameScores
205- // FIXME: Realm (ahem, I mean the atlas device sdk *rolls eyes*) is a fucking joke.
206- // Realm doesn't support .Contains on IList<T>. Yes, really.
207- // This means we are forced to iterate over EVERY SCORE.
208- // I can't wait for Postgres.
209- . AsEnumerableIfRealm ( )
210- . Where ( s => s . PlayerIdsRaw . Contains ( user . UserId . ToString ( ) ) )
211- . ToArrayIfPostgres ( ) ;
212-
213- this . Write ( ( ) =>
212+ . Where ( s => s . PublisherId == user . UserId && s . Rank != 0 )
213+ . ToArray ( ) ;
214+
215+ this . GameScores . RemoveRange ( s => s . PublisherId == user . UserId ) ;
216+ this . Events . RemoveRange ( s => s . StoredDataType == EventDataType . Score && s . UserId == user . UserId ) ;
217+ this . SaveChanges ( ) ;
218+
219+ foreach ( GameScore score in scores )
214220 {
215- foreach ( GameScore score in scores )
216- {
217- IQueryable < Event > scoreEvents = this . Events
218- . Where ( e => e . StoredDataType == EventDataType . Score && e . StoredObjectId == score . ScoreId ) ;
219-
220- this . Events . RemoveRange ( scoreEvents ) ;
221- this . GameScores . Remove ( score ) ;
222- }
223- } ) ;
221+ this . RecalculateScoreStatistics ( score . LevelId , score . ScoreType , false ) ;
222+ }
223+ this . SaveChanges ( ) ;
224224 }
225225
226226 public IEnumerable < GameUser > GetPlayersFromScore ( GameScore score )
0 commit comments