From 5a260c3e2100087184a6a4af75c39ab446843ea1 Mon Sep 17 00:00:00 2001 From: Toaster Date: Sat, 9 Aug 2025 20:45:19 +0200 Subject: [PATCH 1/2] Pin progress creation/updating fixes and improvements --- Refresh.Database/GameDatabaseContext.Pins.cs | 164 ++++++++---------- .../{ManuallyAwardedPins.cs => ServerPins.cs} | 0 RefreshTests.GameServer/TestContext.cs | 3 +- .../Tests/Pins/PinProgressUpdatingTests.cs | 2 +- .../Tests/Pins/ScorePinTests.cs | 29 +++- 5 files changed, 106 insertions(+), 92 deletions(-) rename Refresh.Database/Models/Pins/{ManuallyAwardedPins.cs => ServerPins.cs} (100%) diff --git a/Refresh.Database/GameDatabaseContext.Pins.cs b/Refresh.Database/GameDatabaseContext.Pins.cs index ce444b7e5..4001a346e 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; } - }); + } + 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 + } + } + 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); + + 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); + 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..da35f4784 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 = 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] From 3b911c9bd655e669562a5851a2e232fac96b9009 Mon Sep 17 00:00:00 2001 From: Toaster Date: Sun, 10 Aug 2025 18:57:21 +0200 Subject: [PATCH 2/2] Prefix 'this.' to some method calls --- Refresh.Database/GameDatabaseContext.Pins.cs | 8 ++++---- RefreshTests.GameServer/TestContext.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Refresh.Database/GameDatabaseContext.Pins.cs b/Refresh.Database/GameDatabaseContext.Pins.cs index 4001a346e..145619162 100644 --- a/Refresh.Database/GameDatabaseContext.Pins.cs +++ b/Refresh.Database/GameDatabaseContext.Pins.cs @@ -50,7 +50,7 @@ public void UpdateUserPinProgress(Dictionary pinProgressUpdates, Game existingProgress.LastUpdated = now; } } - SaveChanges(); + this.SaveChanges(); } public void UpdateUserProfilePins(List pinUpdates, GameUser user, TokenGame game) @@ -90,7 +90,7 @@ public void UpdateUserProfilePins(List pinUpdates, GameUser user, TokenGam existingPinAtIndex.Timestamp = now; // New pin at this position: reset timestamp } } - SaveChanges(); + this.SaveChanges(); } public PinProgressRelation UpdateUserPinProgressToLowest(long pinId, int newProgressValue, GameUser user, bool isBeta) @@ -131,13 +131,13 @@ public void IncrementUserPinProgress(long pinId, int progressToAdd, GameUser use this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, true); this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, false); - SaveChanges(); + this.SaveChanges(); } public PinProgressRelation IncrementUserPinProgress(long pinId, int progressToAdd, GameUser user, bool isBeta) { PinProgressRelation relation = this.IncrementUserPinProgressInternal(pinId, progressToAdd, user, isBeta); - SaveChanges(); + this.SaveChanges(); return relation; } diff --git a/RefreshTests.GameServer/TestContext.cs b/RefreshTests.GameServer/TestContext.cs index da35f4784..31db7c558 100644 --- a/RefreshTests.GameServer/TestContext.cs +++ b/RefreshTests.GameServer/TestContext.cs @@ -148,7 +148,7 @@ public void FillLeaderboard(GameLevel level, int count, byte type) for (byte i = 0; i < count; i++) { string username = "score" + i; - GameUser scoreUser = Database.GetUserByUsername(username) ?? this.CreateUser(username); + GameUser scoreUser = this.Database.GetUserByUsername(username) ?? this.CreateUser(username); this.SubmitScore(i, type, level, scoreUser, TokenGame.LittleBigPlanet2, TokenPlatform.PS3); } }