Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 75 additions & 89 deletions Refresh.Database/GameDatabaseContext.Pins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,39 @@ public void UpdateUserPinProgress(Dictionary<long, int> pinProgressUpdates, Game
(long)ServerPins.TopXOfAnyCommunityLevelWithOver50Scores,
];

this.Write(() =>
foreach (KeyValuePair<long, int> pinProgressUpdate in pinProgressUpdates)
{
foreach (KeyValuePair<long, int> 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<long> pinUpdates, GameUser user, TokenGame game)
Expand All @@ -61,40 +59,38 @@ public void UpdateUserProfilePins(List<long> pinUpdates, GameUser user, TokenGam
IEnumerable<ProfilePinRelation> 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)
Expand All @@ -105,53 +101,43 @@ 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!;
}

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;
}
Expand Down Expand Up @@ -180,7 +166,7 @@ private PinProgressRelation IncrementUserPinProgressInternal(long pinId, int pro
}
else
{
progressToUpdate.Progress =+ progressToAdd;
progressToUpdate.Progress += progressToAdd;
progressToUpdate.LastUpdated = now;
}

Expand Down
3 changes: 2 additions & 1 deletion RefreshTests.GameServer/TestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
29 changes: 28 additions & 1 deletion RefreshTests.GameServer/Tests/Pins/ScorePinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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;
Expand All @@ -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]
Expand Down