Remove duplicate scores (#622)

* Remove duplicate scores

* Optimize score migration
This commit is contained in:
Josh 2023-01-10 17:36:43 -06:00 committed by GitHub
parent c86d2a11b5
commit b5877bc10c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 32 deletions

View file

@ -29,7 +29,7 @@ public class ScoreController : ControllerBase
[HttpPost("scoreboard/{slotType}/{id:int}")]
[HttpPost("scoreboard/{slotType}/{id:int}/{childId:int}")]
public async Task<IActionResult> SubmitScore(string slotType, int id, int childId, [FromQuery] bool lbp1 = false, [FromQuery] bool lbp2 = false, [FromQuery] bool lbp3 = false)
public async Task<IActionResult> SubmitScore(string slotType, int id, int childId)
{
GameToken token = this.GetToken();
@ -49,7 +49,7 @@ public class ScoreController : ControllerBase
}
// This only seems to happens on lbp2 versus levels, not sure why
if(score.PlayerIdCollection.Contains(':'))
if (score.PlayerIdCollection.Contains(':'))
score.PlayerIdCollection = score.PlayerIdCollection.Replace(':', ',');
if (score.PlayerIds.Length == 0)
@ -111,21 +111,14 @@ public class ScoreController : ControllerBase
case GameVersion.LittleBigPlanet3:
slot.PlaysLBP3Complete++;
break;
case GameVersion.LittleBigPlanetPSP: break;
case GameVersion.Unknown: break;
case GameVersion.LittleBigPlanetPSP:
case GameVersion.Unknown:
default: throw new ArgumentOutOfRangeException();
}
// Submit scores from all players in lobby
foreach (string player in score.PlayerIds)
{
List<string> players = new();
players.Add(player); // make sure this player is first
players.AddRange(score.PlayerIds.Where(p => p != player));
Score playerScore = new()
{
PlayerIdCollection = string.Join(',', players),
PlayerIdCollection = string.Join(',', score.PlayerIds),
Type = score.Type,
Points = score.Points,
SlotId = score.SlotId,
@ -147,7 +140,6 @@ public class ScoreController : ControllerBase
{
this.database.Scores.Add(playerScore);
}
}
await this.database.SaveChangesAsync();

View file

@ -42,11 +42,17 @@
@for (int j = 0; j < playerIds.Length; j++)
{
User? user = await database.Users.FirstOrDefaultAsync(u => u.Username == playerIds[j]);
if (user == null) continue;
<div class="item">
<i class="minus icon" style="padding-top: 9px"></i>
<div class="content" style="padding-left: 0">
@if (user != null)
{
@await user.ToLink(Html, ViewData, language, timeZone)
}
else
{
<p style="margin-top: 5px;">@playerIds[j]</p>
}
</div>
</div>
}

View file

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.MigrationTasks;
public class CleanupDuplicateScoresMigration : IMigrationTask
{
public string Name() => "Cleanup duplicate scores";
public async Task<bool> Run(Database database)
{
List<int> duplicateScoreIds = new();
// The original score should have the lowest score id
foreach (Score score in database.Scores.OrderBy(s => s.ScoreId)
.ToList()
.Where(score => !duplicateScoreIds.Contains(score.ScoreId)))
{
foreach (Score other in database.Scores.Where(s =>
s.Points == score.Points &&
s.Type == score.Type &&
s.SlotId == score.SlotId &&
s.ScoreId != score.ScoreId &&
s.ChildSlotId == score.ChildSlotId &&
s.ScoreId > score.ScoreId))
{
if (score.PlayerIds.Length != other.PlayerIds.Length)
continue;
HashSet<string> hashSet = new(score.PlayerIds);
if (!other.PlayerIds.All(hashSet.Contains)) continue;
Logger.Info($"Removing score with id {other.ScoreId}, slotId={other.SlotId} main='{score.PlayerIdCollection}', duplicate={other.PlayerIdCollection}", LogArea.Score);
database.Scores.Remove(other);
duplicateScoreIds.Add(other.ScoreId);
}
}
Logger.Info($"Removed a total of {duplicateScoreIds.Count} duplicate scores", LogArea.Score);
await database.SaveChangesAsync();
return true;
}
}