diff --git a/Refresh.Database/GameDatabaseContext.Pins.cs b/Refresh.Database/GameDatabaseContext.Pins.cs index ce444b7e5..145619162 100644 --- a/Refresh.Database/GameDatabaseContext.Pins.cs +++ b/Refresh.Database/GameDatabaseContext.Pins.cs @@ -18,41 +18,39 @@ public void UpdateUserPinProgress(Dictionary pinProgressUpdates, Game (long)ServerPins.TopXOfAnyCommunityLevelWithOver50Scores, ]; - this.Write(() => + foreach (KeyValuePair pinProgressUpdate in pinProgressUpdates) { - foreach (KeyValuePair pinProgressUpdate in pinProgressUpdates) - { - long pinId = pinProgressUpdate.Key; - int newProgress = pinProgressUpdate.Value; - PinProgressRelation? existingProgress = existingProgresses.FirstOrDefault(p => p.PinId == pinId); + long pinId = pinProgressUpdate.Key; + int newProgress = pinProgressUpdate.Value; + PinProgressRelation? existingProgress = existingProgresses.FirstOrDefault(p => p.PinId == pinId); - if (existingProgress == null) - { - PinProgressRelation newRelation = new() - { - PinId = pinId, - Progress = newProgress, - Publisher = user, - FirstPublished = now, - LastUpdated = now, - IsBeta = isBeta, - }; - this.PinProgressRelations.Add(newRelation); - continue; - } - - bool isSpecialTreatmentPin = descendingProgressPins.Contains(pinId); - - // Only update progress if it's better. For most pins it's better the greater it is, but for the pins in - // specialTreatmentPins, it's better the smaller it is. - if (!isSpecialTreatmentPin && newProgress > existingProgress.Progress - || isSpecialTreatmentPin && newProgress < existingProgress.Progress) + if (existingProgress == null) + { + PinProgressRelation newRelation = new() { - existingProgress.Progress = newProgress; - existingProgress.LastUpdated = now; - } + PinId = pinId, + Progress = newProgress, + Publisher = user, + FirstPublished = now, + LastUpdated = now, + IsBeta = isBeta, + }; + this.PinProgressRelations.Add(newRelation); + continue; + } + + bool isSpecialTreatmentPin = descendingProgressPins.Contains(pinId); + + // Only update progress if it's better. For most pins it's better the greater it is, but for the pins in + // specialTreatmentPins, it's better the smaller it is. + if ((!isSpecialTreatmentPin && newProgress > existingProgress.Progress) + || (isSpecialTreatmentPin && newProgress < existingProgress.Progress)) + { + existingProgress.Progress = newProgress; + existingProgress.LastUpdated = now; } - }); + } + this.SaveChanges(); } public void UpdateUserProfilePins(List pinUpdates, GameUser user, TokenGame game) @@ -61,40 +59,38 @@ public void UpdateUserProfilePins(List pinUpdates, GameUser user, TokenGam IEnumerable existingProfilePins = this.GetProfilePinsByUser(user, game); DateTimeOffset now = this._time.Now; - this.Write(() => + for (int i = 0; i < pinUpdates.Count; i++) { - for (int i = 0; i < pinUpdates.Count; i++) - { - long progressType = pinUpdates[i]; + long progressType = pinUpdates[i]; - // Does the user have any progress on the new pin? - if (!existingProgressIds.Contains(progressType)) continue; + // Does the user have any progress on the new pin? + if (!existingProgressIds.Contains(progressType)) continue; - ProfilePinRelation? existingPinAtIndex = existingProfilePins.FirstOrDefault(p => p.Index == i); + ProfilePinRelation? existingPinAtIndex = existingProfilePins.FirstOrDefault(p => p.Index == i); - // If the pin at this position hasn't changed, skip it - if (existingPinAtIndex?.PinId == progressType) continue; + // If the pin at this position hasn't changed, skip it + if (existingPinAtIndex?.PinId == progressType) continue; - if (existingPinAtIndex == null) - { - this.ProfilePinRelations.Add(new() - { - PinId = progressType, - Publisher = user, - PublisherId = user.UserId, - Index = i, - Game = game, - Timestamp = now, - }); - } - else + if (existingPinAtIndex == null) + { + this.ProfilePinRelations.Add(new() { - this.ProfilePinRelations.Update(existingPinAtIndex); - existingPinAtIndex.PinId = progressType; - existingPinAtIndex.Timestamp = now; // New pin at this position: reset timestamp - } + PinId = progressType, + Publisher = user, + PublisherId = user.UserId, + Index = i, + Game = game, + Timestamp = now, + }); } - }); + else + { + this.ProfilePinRelations.Update(existingPinAtIndex); + existingPinAtIndex.PinId = progressType; + existingPinAtIndex.Timestamp = now; // New pin at this position: reset timestamp + } + } + this.SaveChanges(); } public PinProgressRelation UpdateUserPinProgressToLowest(long pinId, int newProgressValue, GameUser user, bool isBeta) @@ -105,30 +101,26 @@ public PinProgressRelation UpdateUserPinProgressToLowest(long pinId, int newProg if (progressToUpdate == null) { - this.Write(() => + progressToUpdate = new() { - progressToUpdate = new() - { - PinId = pinId, - Progress = newProgressValue, - Publisher = user, - PublisherId = user.UserId, - FirstPublished = now, - LastUpdated = now, - IsBeta = isBeta, - }; + PinId = pinId, + Progress = newProgressValue, + Publisher = user, + PublisherId = user.UserId, + FirstPublished = now, + LastUpdated = now, + IsBeta = isBeta, + }; - this.PinProgressRelations.Add(progressToUpdate); - }); + this.PinProgressRelations.Add(progressToUpdate); + SaveChanges(); } // Only update if the final progress value is actually lower to the one already set else if (newProgressValue < progressToUpdate.Progress) { - this.Write(() => - { - progressToUpdate.Progress = newProgressValue; - progressToUpdate.LastUpdated = now; - }); + progressToUpdate.Progress = newProgressValue; + progressToUpdate.LastUpdated = now; + SaveChanges(); } return progressToUpdate!; @@ -136,22 +128,16 @@ public PinProgressRelation UpdateUserPinProgressToLowest(long pinId, int newProg public void IncrementUserPinProgress(long pinId, int progressToAdd, GameUser user) { - this.Write(() => - { - this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, true); - this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, false); - }); - + this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, true); + this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, false); + + this.SaveChanges(); } public PinProgressRelation IncrementUserPinProgress(long pinId, int progressToAdd, GameUser user, bool isBeta) { - PinProgressRelation relation = null!; - - this.Write(() => - { - relation = this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, isBeta); - }); + PinProgressRelation relation = this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, isBeta); + this.SaveChanges(); return relation; } @@ -180,7 +166,7 @@ private PinProgressRelation IncrementUserPinProgressInternal(long pinId, int pro } else { - progressToUpdate.Progress =+ progressToAdd; + progressToUpdate.Progress += progressToAdd; progressToUpdate.LastUpdated = now; } diff --git a/Refresh.Database/Models/Pins/ManuallyAwardedPins.cs b/Refresh.Database/Models/Pins/ServerPins.cs similarity index 100% rename from Refresh.Database/Models/Pins/ManuallyAwardedPins.cs rename to Refresh.Database/Models/Pins/ServerPins.cs diff --git a/RefreshTests.GameServer/TestContext.cs b/RefreshTests.GameServer/TestContext.cs index 3563eb873..31db7c558 100644 --- a/RefreshTests.GameServer/TestContext.cs +++ b/RefreshTests.GameServer/TestContext.cs @@ -147,7 +147,8 @@ public void FillLeaderboard(GameLevel level, int count, byte type) { for (byte i = 0; i < count; i++) { - GameUser scoreUser = this.CreateUser("score" + i); + string username = "score" + i; + GameUser scoreUser = this.Database.GetUserByUsername(username) ?? this.CreateUser(username); this.SubmitScore(i, type, level, scoreUser, TokenGame.LittleBigPlanet2, TokenPlatform.PS3); } } diff --git a/RefreshTests.GameServer/Tests/Pins/PinProgressUpdatingTests.cs b/RefreshTests.GameServer/Tests/Pins/PinProgressUpdatingTests.cs index 23c7c70f8..83732c2e3 100644 --- a/RefreshTests.GameServer/Tests/Pins/PinProgressUpdatingTests.cs +++ b/RefreshTests.GameServer/Tests/Pins/PinProgressUpdatingTests.cs @@ -6,7 +6,7 @@ using Refresh.Interfaces.Game.Types.Pins; using RefreshTests.GameServer.Extensions; -namespace RefreshTests.GameServer.Tests.Levels; +namespace RefreshTests.GameServer.Tests.Pins; public class PinProgressUpdatingTests : GameServerTest { diff --git a/RefreshTests.GameServer/Tests/Pins/ScorePinTests.cs b/RefreshTests.GameServer/Tests/Pins/ScorePinTests.cs index 66b6811a2..0f8475eda 100644 --- a/RefreshTests.GameServer/Tests/Pins/ScorePinTests.cs +++ b/RefreshTests.GameServer/Tests/Pins/ScorePinTests.cs @@ -6,7 +6,7 @@ using Refresh.Interfaces.Game.Types.UserData.Leaderboard; using RefreshTests.GameServer.Extensions; -namespace RefreshTests.GameServer.Tests.Levels; +namespace RefreshTests.GameServer.Tests.Pins; public class ScorePinTests : GameServerTest { @@ -82,6 +82,7 @@ public void AchieveTopFourthOfXLeaderboardsPin(byte scoreType, bool isStoryLevel long pinIdToCheck = isStoryLevel ? (long)ServerPins.TopFourthOfXStoryLevelsWithOver50Scores : (long)ServerPins.TopFourthOfXCommunityLevelsWithOver50Scores; + // ROUND 1: Adding the pin // Create a level and spam it with scores by others GameLevel level = isStoryLevel ? context.Database.GetStoryLevelById(1) : context.CreateLevel(user); int levelId = isStoryLevel ? level.StoryId : level.LevelId; @@ -105,6 +106,32 @@ public void AchieveTopFourthOfXLeaderboardsPin(byte scoreType, bool isStoryLevel PinProgressRelation? relation = context.Database.GetUserPinProgress(pinIdToCheck, user, false); Assert.That(relation, Is.Not.Null); Assert.That(relation!.Progress, Is.EqualTo(1)); + + // ROUND 2: Updating the pin + // Create another level and spam it with scores by others aswell + GameLevel level2 = isStoryLevel ? context.Database.GetStoryLevelById(2) : context.CreateLevel(user); + int levelId2 = isStoryLevel ? level2.StoryId : level2.LevelId; + + context.FillLeaderboard(level2, 100, scoreType); + + // Now post our score which will definitely make it to the top 25% here aswell + SerializedScore score2 = new() + { + Host = true, + ScoreType = scoreType, + Score = 80, + }; + + context.Database.PlayLevel(level2, user, 1); + message = client.PostAsync($"/lbp/scoreboard/{slotType}/{levelId2}", new StringContent(score2.AsXML())).Result; + Assert.That(message.StatusCode, Is.EqualTo(OK)); + + context.Database.Refresh(); + + // Ensure the pin progress has been incremented + PinProgressRelation? relation2 = context.Database.GetUserPinProgress(pinIdToCheck, user, false); + Assert.That(relation2, Is.Not.Null); + Assert.That(relation2!.Progress, Is.EqualTo(2)); } [Test]