From 66bb9f0a8283de08257d61e8d60e5b521afbf533 Mon Sep 17 00:00:00 2001 From: Hipposgrumm Date: Wed, 11 Jun 2025 14:59:42 -0600 Subject: [PATCH 1/5] Daily Scoreboard now works correctly. --- src/Controllers/Common/ContentController.cs | 2 +- src/Model/DBContext.cs | 14 +++++ src/Model/DailyHighscore.cs | 15 +++++ src/Model/DailyHighscorePair.cs | 13 +++++ src/Model/Viking.cs | 1 + src/Services/GameDataService.cs | 62 ++++++++++++++++++++- 6 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/Model/DailyHighscore.cs create mode 100644 src/Model/DailyHighscorePair.cs diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 52dea2b..cb2745f 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -2150,7 +2150,7 @@ public class ContentController : Controller { [Route("ContentWebService.asmx/GetPeriodicGameDataByGame")] // used by Math Blaster and WoJS (probably from 24 hours ago to now) [VikingSession(UseLock = true)] public IActionResult GetPeriodicGameDataByGame(Viking viking, [FromForm] int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, int score, bool buddyFilter, string apiKey) { - return Ok(gameDataService.GetGameData(viking, gameId, isMultiplayer, difficulty, gameLevel, key, count, AscendingOrder, buddyFilter, apiKey, DateTime.Now.AddHours(-24), DateTime.Now)); + return Ok(gameDataService.GetDailyGameData(viking, gameId, isMultiplayer, difficulty, gameLevel, key, count, AscendingOrder, buddyFilter, apiKey)); } [HttpPost] diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index 1832763..ce01bc0 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -19,6 +19,8 @@ public class DBContext : DbContext { public DbSet RoomItems { get; set; } = null!; public DbSet GameData { get; set; } = null!; public DbSet GameDataPairs { get; set; } = null!; + public DbSet DailyHighscores { get; set; } = null!; + public DbSet DailyHighscorePairs { get; set; } = null!; public DbSet AchievementPoints { get; set; } = null!; public DbSet ProfileAnswers { get; set; } = null!; public DbSet MMORoles { get; set; } = null!; @@ -129,6 +131,9 @@ public class DBContext : DbContext { builder.Entity().HasMany(v => v.GameData) .WithOne(e => e.Viking); + builder.Entity().HasMany(v => v.DailyHighscores) + .WithOne(e => e.Viking); + builder.Entity().HasMany(v => v.SavedData) .WithOne(e => e.Viking); @@ -222,6 +227,15 @@ public class DBContext : DbContext { builder.Entity().HasOne(e => e.GameData) .WithMany(e => e.GameDataPairs); + builder.Entity().HasOne(e => e.Viking) + .WithMany(e => e.DailyHighscores); + + builder.Entity().HasMany(e => e.ScorePairs) + .WithOne(e => e.DailyScore); + + builder.Entity().HasOne(e => e.DailyScore) + .WithMany(e => e.ScorePairs); + // Others .. builder.Entity().HasOne(s => s.Viking) .WithMany(e => e.Images) diff --git a/src/Model/DailyHighscore.cs b/src/Model/DailyHighscore.cs new file mode 100644 index 0000000..4d89c0f --- /dev/null +++ b/src/Model/DailyHighscore.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace sodoff.Model; + +public class DailyHighscore { + [Key] + public int Id { get; set; } + public int VikingId { get; set; } + public int GameId { get; set; } + public int Difficulty { get; set; } + public int GameLevel { get; set; } + public bool IsMultiplayer { get; set; } + public virtual ICollection ScorePairs { get; set; } = null!; + public virtual Viking Viking { get; set; } = null!; +} diff --git a/src/Model/DailyHighscorePair.cs b/src/Model/DailyHighscorePair.cs new file mode 100644 index 0000000..6b312f3 --- /dev/null +++ b/src/Model/DailyHighscorePair.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace sodoff.Model; + +public class DailyHighscorePair { + [Key] + public int Id { get; set; } + public int DailyScoreId { get; set; } + public string Name { get; set; } = null!; + public int Value { get; set; } + public DateTime DatePlayed { get; set; } + public virtual DailyHighscore DailyScore { get; set; } = null!; +} diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index a787107..cd19e70 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -34,6 +34,7 @@ public class Viking { public virtual ICollection PairData { get; set; } = null!; public virtual ICollection InventoryItems { get; set; } = null!; public virtual ICollection GameData { get; set; } = null!; + public virtual ICollection DailyHighscores { get; set; } = null!; public virtual ICollection ProfileAnswers { get; set; } = null!; public virtual ICollection SavedData { get; set; } = null!; public virtual ICollection Parties { get; set; } = null!; diff --git a/src/Services/GameDataService.cs b/src/Services/GameDataService.cs index 8814586..b76216a 100644 --- a/src/Services/GameDataService.cs +++ b/src/Services/GameDataService.cs @@ -32,8 +32,21 @@ public class GameDataService { } gameData.DatePlayed = DateTime.UtcNow; - SavePairs(gameData, xmlDocumentData); + + DailyHighscore? daily = viking.DailyHighscores.FirstOrDefault(x => x.GameId == gameId && x.IsMultiplayer == isMultiplayer && x.Difficulty == difficulty && x.GameLevel == gameLevel); + if (daily == null) { + daily = new DailyHighscore { + GameId = gameId, + Difficulty = difficulty, + GameLevel = gameLevel, + IsMultiplayer = isMultiplayer, + ScorePairs = new List() + }; + viking.DailyHighscores.Add(daily); + } + SavePairs(gameData, daily, xmlDocumentData); ctx.SaveChanges(); + return true; } @@ -70,6 +83,30 @@ public class GameDataService { return GetSummaryFromResponse(viking, isMultiplayer, difficulty, gameLevel, key, selectedData); } + + public GameDataSummary GetDailyGameData(Viking viking, int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, bool buddyFilter, string apiKey) { + IQueryable query = ctx.DailyHighscores + .Where(x => x.GameId == gameId && x.IsMultiplayer == false && x.Difficulty == difficulty && x.GameLevel == gameLevel) + .SelectMany(e => e.ScorePairs).Where(x => x.DatePlayed == DateTime.Today && x.Name == key); + + // TODO: Buddy filter + + if (AscendingOrder) query = query.OrderBy(e => e.Value); + else query = query.OrderByDescending(e => e.Value); + + List selectedData; + if (ClientVersion.GetVersion(apiKey) <= ClientVersion.Max_OldJS) + // use DisplayName instead of Name + selectedData = query.Select(e => new GameDataResponse( + XmlUtil.DeserializeXml(e.DailyScore.Viking.AvatarSerialized).DisplayName, e.DailyScore.Viking.Uid, e.DatePlayed, false, false, e.Value) + ).Take(count).ToList(); + else + selectedData = query.Select(e => new GameDataResponse( + e.DailyScore.Viking.Name, e.DailyScore.Viking.Uid, e.DatePlayed, false, false, e.Value) + ).Take(count).ToList(); + + return GetSummaryFromResponse(viking, isMultiplayer, difficulty, gameLevel, key, selectedData); + } // ByUser for JumpStart's My Scores public GameDataSummary GetGameDataByUser(Viking viking, int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, string apiKey) { @@ -138,7 +175,7 @@ public class GameDataService { return gameData; } - private void SavePairs(Model.GameData gameData, string xmlDocumentData) { + private void SavePairs(Model.GameData gameData, DailyHighscore daily, string xmlDocumentData) { foreach (var pair in GetGameDataPairs(xmlDocumentData)) { GameDataPair? dbPair = gameData.GameDataPairs.FirstOrDefault(x => x.Name == pair.Name); if (dbPair == null) @@ -147,6 +184,27 @@ public class GameDataService { dbPair.Value = pair.Value; else if (pair.Name != "time" && dbPair.Value <= pair.Value) dbPair.Value = pair.Value; + + DailyHighscorePair? dailyPair = daily.ScorePairs.FirstOrDefault(x => x.Name == pair.Name); + if (dailyPair == null) { + daily.Difficulty = gameData.Difficulty; + daily.GameLevel = gameData.GameLevel; + dailyPair = new DailyHighscorePair { + Name = pair.Name, + Value = pair.Value, + DatePlayed = DateTime.Today + }; + daily.ScorePairs.Add(dailyPair); + } else if ( + (pair.Name == "time" && dailyPair.Value > pair.Value) || // Better Time + (pair.Name != "time" && dailyPair.Value <= pair.Value) || // Better Score + dailyPair.DatePlayed != DateTime.Today // Another Day + ) { + daily.Difficulty = gameData.Difficulty; + daily.GameLevel = gameData.GameLevel; + dailyPair.DatePlayed = DateTime.Today; + dailyPair.Value = pair.Value; + } } } From e5fe602ade923569c1f3f6cda188217098ee7597 Mon Sep 17 00:00:00 2001 From: Hipposgrumm Date: Sat, 14 Jun 2025 15:12:27 -0600 Subject: [PATCH 2/5] "Rewrote" party creation system, added support for supersecret parties. --- src/Controllers/Common/ContentController.cs | 133 +++++++++++++------- src/Model/Party.cs | 3 + 2 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 52dea2b..3dbeeae 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1393,6 +1393,9 @@ public class ContentController : Controller { List allParties = ctx.Parties.ToList(); List userParties = new List(); + uint gameVersion = ClientVersion.GetVersion(apiKey); + if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0) + gameVersion = ClientVersion.WoJS; // This can be optimized. It's also a shortcut. foreach(var party in allParties) { if(DateTime.UtcNow >= party.ExpirationDate) @@ -1403,6 +1406,8 @@ public class ContentController : Controller { continue; } + // Only send parties to their respective games. + if (gameVersion != party.GameVersion) continue; Viking viking = ctx.Vikings.FirstOrDefault(e => e.Id == party.VikingId); AvatarData avatarData = XmlUtil.DeserializeXml(viking.AvatarSerialized); @@ -1411,34 +1416,29 @@ public class ContentController : Controller { DisplayName = avatarData.DisplayName, UserName = avatarData.DisplayName, ExpirationDate = party.ExpirationDate, - Icon = party.LocationIconAsset, + Icon = party.IconAsset, Location = party.Location, + LocationIcon = party.LocationIconAsset, PrivateParty = party.PrivateParty!.Value, UserID = viking.Uid }; - if (party.Location == "MyNeighborhood") userParty.DisplayName = $"{userParty.UserName}'s Block Party"; - if (party.Location == "MyVIPRoomInt") userParty.DisplayName = $"{userParty.UserName}'s VIP Party"; - if (party.Location == "MyPodInt") { - // Only way to do this without adding another column to the table. - if (party.AssetBundle == "RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty") { - userParty.DisplayName = $"{userParty.UserName}'s Pod Birthday Party"; - } else { - userParty.DisplayName = $"{userParty.UserName}'s Pod Party"; - } - } + string location = party.Location switch { + "MyNeighborhood" => "Block ", + "MyPodInt" => "Pod ", + "MyLoungeSSInt" => "Lounge ", + _ => "" + }; + string type = party.PartyType switch { + "VIPRoom" => "VIP ", + "Birthday" => "Birthday ", + "NewYears" => "New Years ", + "Holiday" => "Holiday ", + _ => "" + }; + userParty.DisplayName = $"{userParty.UserName}'s {location}{type}Party"; // Spaces are included in the location and type when they aren't empty. - uint gameVersion = ClientVersion.GetVersion(apiKey); - // Send only JumpStart parties to JumpStart - if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0 - && (party.Location == "MyNeighborhood" - || party.Location == "MyVIPRoomInt")) { - userParties.Add(userParty); - // Send only Math Blaster parties to Math Blaster - } else if (gameVersion == ClientVersion.MB - && party.Location == "MyPodInt") { - userParties.Add(userParty); - } + userParties.Add(userParty); } return Ok(new UserPartyData { NonBuddyParties = userParties.ToArray() }); @@ -1473,8 +1473,9 @@ public class ContentController : Controller { DisplayName = avatarData.DisplayName, UserName = avatarData.DisplayName, ExpirationDate = party.ExpirationDate, - Icon = party.LocationIconAsset, + Icon = party.IconAsset, Location = party.Location, + LocationIcon = party.LocationIconAsset, PrivateParty = party.PrivateParty!.Value, UserID = viking.Uid, AssetBundle = party.AssetBundle @@ -1496,12 +1497,6 @@ public class ContentController : Controller { { ItemData itemData = itemService.GetItem(itemId); - // create a party based on bought itemid - Party party = new Party - { - PrivateParty = false - }; - string? partyType = itemData.Attribute?.FirstOrDefault(a => a.Key == "PartyType").Value; if (partyType is null) { @@ -1509,26 +1504,68 @@ public class ContentController : Controller { } uint gameVersion = ClientVersion.GetVersion(apiKey); - if (partyType == "Default") { - if (gameVersion == ClientVersion.MB) { + if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0) + gameVersion = ClientVersion.WoJS; // This can be optimized. It's also a shortcut. + + // create a party based on bought itemid + Party party = new Party { + PrivateParty = false, + GameVersion = gameVersion, + PartyType = partyType + }; + + switch (gameVersion) { + case ClientVersion.WoJS: + party.Location = "MyVIPRoomInt"; + party.IconAsset = "RS_DATA/Parties01.unity3d/IcoPartyDefault"; + party.LocationIconAsset = "RS_DATA/Parties01.unity3d/IcoPartyLocationVIPRoom"; + if (partyType == "VIPRoom") { + party.AssetBundle = "RS_DATA/PfMyVIPRoomIntPartyGroup.unity3d/PfMyVIPRoomIntPartyGroup"; + } else if (partyType == "Holiday") { + party.IconAsset = "RS_DATA/Parties01.unity3d/IcoPartyDefault"; + party.AssetBundle = "RS_DATA/PfMyVIPRoomIntXmasGroup.unity3d/PfMyVIPRoomIntXmasGroup"; + } else { + party.Location = "MyNeighborhood"; + party.LocationIconAsset = "RS_DATA/Parties01.unity3d/IcoPartyLocationMyNeighborhood"; + party.AssetBundle = "RS_DATA/PfMyNeighborhoodParty.unity3d/PfMyNeighborhoodParty"; + } + break; + case ClientVersion.MB: party.Location = "MyPodInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyDefault"; - party.AssetBundle = "RS_DATA/PfMyPodParty.unity3d/PfMyPodParty"; - } else { - party.Location = "MyNeighborhood"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesList.unity3d/IcoPartyLocationMyNeighborhood"; - party.AssetBundle = "RS_DATA/PfMyNeighborhoodParty.unity3d/PfMyNeighborhoodParty"; - } - } else if (partyType == "VIPRoom") { - party.Location = "MyVIPRoomInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesList.unity3d/IcoPartyDefault"; - party.AssetBundle = "RS_DATA/PfMyVIPRoomIntPartyGroup.unity3d/PfMyVIPRoomIntPartyGroup"; - } else if (partyType == "Birthday") { - party.Location = "MyPodInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyBirthday"; - party.AssetBundle = "RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty"; - } else { - Console.WriteLine($"Unsupported partyType = {partyType}"); + if (partyType == "Birthday") { + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyBirthday"; + party.AssetBundle = "RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty"; + } else { + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyDefault"; + party.AssetBundle = "RS_DATA/PfMyPodParty.unity3d/PfMyPodParty"; + } + break; + case ClientVersion.SS: + party.Location = "MyLoungeSSInt"; + switch (partyType) { + case "Birthday": + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoSSStorePartyBirthdayDefault"; + party.AssetBundle = "RS_DATA/PfSsRoomInteriorBirthdayGroup.unity3d/PfSsRoomInteriorBirthdayGroup"; + break; + case "NewYears": + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoSSStorePartyNewYearDefault"; + party.AssetBundle = "RS_DATA/PfSsRoomInteriorNewYearGroup.unity3d/PfSsRoomInteriorNewYearGroup"; + break; + case "Holiday": + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoSSStorePartyHolidayDefault"; + party.AssetBundle = "RS_DATA/PfSsRoomInteriorHolidayGroup.unity3d/PfSsRoomInteriorHolidayGroup"; + break; + default: + party.IconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoSSStorePartyDefault"; + party.AssetBundle = "RS_DATA/PfSsRoomInteriorPartyGroup.unity3d/PfSsRoomInteriorPartyGroup"; + break; + } + break; + } + + + if (party.Location == null) { + Console.WriteLine($"Unsupported partyType \"{partyType}\" for gameversion 0x{gameVersion:X8}"); return Ok(null); } diff --git a/src/Model/Party.cs b/src/Model/Party.cs index 9667da5..4378005 100644 --- a/src/Model/Party.cs +++ b/src/Model/Party.cs @@ -11,8 +11,11 @@ namespace sodoff.Model public int VikingId { get; set; } public DateTime ExpirationDate { get; set; } = DateTime.UtcNow; public bool? PrivateParty { get; set; } + public string IconAsset { get; set; } = null!; public string LocationIconAsset { get; set; } = null!; public string AssetBundle { get; set; } = null!; public virtual Viking? Viking { get; set; } + public uint GameVersion { get; set; } = 0!; + public string PartyType { get; set; } = null!; } } From 17709423b6cd57e04b289b28bb9a3c54bf7e3427 Mon Sep 17 00:00:00 2001 From: Hipposgrumm Date: Sun, 15 Jun 2025 23:07:45 -0600 Subject: [PATCH 3/5] Heavily optimized the entire PR. --- src/Model/DBContext.cs | 14 ------- src/Model/DailyHighscore.cs | 15 ------- src/Model/DailyHighscorePair.cs | 13 ------- src/Model/GameDataPair.cs | 1 + src/Model/Viking.cs | 1 - src/Services/GameDataService.cs | 69 ++++++++++++--------------------- 6 files changed, 25 insertions(+), 88 deletions(-) delete mode 100644 src/Model/DailyHighscore.cs delete mode 100644 src/Model/DailyHighscorePair.cs diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index ce01bc0..1832763 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -19,8 +19,6 @@ public class DBContext : DbContext { public DbSet RoomItems { get; set; } = null!; public DbSet GameData { get; set; } = null!; public DbSet GameDataPairs { get; set; } = null!; - public DbSet DailyHighscores { get; set; } = null!; - public DbSet DailyHighscorePairs { get; set; } = null!; public DbSet AchievementPoints { get; set; } = null!; public DbSet ProfileAnswers { get; set; } = null!; public DbSet MMORoles { get; set; } = null!; @@ -131,9 +129,6 @@ public class DBContext : DbContext { builder.Entity().HasMany(v => v.GameData) .WithOne(e => e.Viking); - builder.Entity().HasMany(v => v.DailyHighscores) - .WithOne(e => e.Viking); - builder.Entity().HasMany(v => v.SavedData) .WithOne(e => e.Viking); @@ -227,15 +222,6 @@ public class DBContext : DbContext { builder.Entity().HasOne(e => e.GameData) .WithMany(e => e.GameDataPairs); - builder.Entity().HasOne(e => e.Viking) - .WithMany(e => e.DailyHighscores); - - builder.Entity().HasMany(e => e.ScorePairs) - .WithOne(e => e.DailyScore); - - builder.Entity().HasOne(e => e.DailyScore) - .WithMany(e => e.ScorePairs); - // Others .. builder.Entity().HasOne(s => s.Viking) .WithMany(e => e.Images) diff --git a/src/Model/DailyHighscore.cs b/src/Model/DailyHighscore.cs deleted file mode 100644 index 4d89c0f..0000000 --- a/src/Model/DailyHighscore.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace sodoff.Model; - -public class DailyHighscore { - [Key] - public int Id { get; set; } - public int VikingId { get; set; } - public int GameId { get; set; } - public int Difficulty { get; set; } - public int GameLevel { get; set; } - public bool IsMultiplayer { get; set; } - public virtual ICollection ScorePairs { get; set; } = null!; - public virtual Viking Viking { get; set; } = null!; -} diff --git a/src/Model/DailyHighscorePair.cs b/src/Model/DailyHighscorePair.cs deleted file mode 100644 index 6b312f3..0000000 --- a/src/Model/DailyHighscorePair.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace sodoff.Model; - -public class DailyHighscorePair { - [Key] - public int Id { get; set; } - public int DailyScoreId { get; set; } - public string Name { get; set; } = null!; - public int Value { get; set; } - public DateTime DatePlayed { get; set; } - public virtual DailyHighscore DailyScore { get; set; } = null!; -} diff --git a/src/Model/GameDataPair.cs b/src/Model/GameDataPair.cs index 9543936..7e029e5 100644 --- a/src/Model/GameDataPair.cs +++ b/src/Model/GameDataPair.cs @@ -7,5 +7,6 @@ public class GameDataPair { public int GameDataId { get; set; } public string Name { get; set; } = null!; public int Value { get; set; } + public int DailyValue { get; set; } public virtual GameData GameData { get; set; } = null!; } diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index cd19e70..a787107 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -34,7 +34,6 @@ public class Viking { public virtual ICollection PairData { get; set; } = null!; public virtual ICollection InventoryItems { get; set; } = null!; public virtual ICollection GameData { get; set; } = null!; - public virtual ICollection DailyHighscores { get; set; } = null!; public virtual ICollection ProfileAnswers { get; set; } = null!; public virtual ICollection SavedData { get; set; } = null!; public virtual ICollection Parties { get; set; } = null!; diff --git a/src/Services/GameDataService.cs b/src/Services/GameDataService.cs index b76216a..2faa29a 100644 --- a/src/Services/GameDataService.cs +++ b/src/Services/GameDataService.cs @@ -31,20 +31,9 @@ public class GameDataService { viking.GameData.Add(gameData); } - gameData.DatePlayed = DateTime.UtcNow; - DailyHighscore? daily = viking.DailyHighscores.FirstOrDefault(x => x.GameId == gameId && x.IsMultiplayer == isMultiplayer && x.Difficulty == difficulty && x.GameLevel == gameLevel); - if (daily == null) { - daily = new DailyHighscore { - GameId = gameId, - Difficulty = difficulty, - GameLevel = gameLevel, - IsMultiplayer = isMultiplayer, - ScorePairs = new List() - }; - viking.DailyHighscores.Add(daily); - } - SavePairs(gameData, daily, xmlDocumentData); + SavePairs(gameData, xmlDocumentData); + gameData.DatePlayed = DateTime.UtcNow; ctx.SaveChanges(); return true; @@ -85,9 +74,12 @@ public class GameDataService { } public GameDataSummary GetDailyGameData(Viking viking, int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, bool buddyFilter, string apiKey) { - IQueryable query = ctx.DailyHighscores - .Where(x => x.GameId == gameId && x.IsMultiplayer == false && x.Difficulty == difficulty && x.GameLevel == gameLevel) - .SelectMany(e => e.ScorePairs).Where(x => x.DatePlayed == DateTime.Today && x.Name == key); + IQueryable query = ctx.GameData + .Where(x => + x.GameId == gameId && x.IsMultiplayer == false && + x.Difficulty == difficulty && x.GameLevel == gameLevel && + x.DatePlayed.Date == DateTime.UtcNow.Date + ).SelectMany(e => e.GameDataPairs).Where(x => x.Name == key); // TODO: Buddy filter @@ -98,11 +90,11 @@ public class GameDataService { if (ClientVersion.GetVersion(apiKey) <= ClientVersion.Max_OldJS) // use DisplayName instead of Name selectedData = query.Select(e => new GameDataResponse( - XmlUtil.DeserializeXml(e.DailyScore.Viking.AvatarSerialized).DisplayName, e.DailyScore.Viking.Uid, e.DatePlayed, false, false, e.Value) + XmlUtil.DeserializeXml(e.GameData.Viking.AvatarSerialized).DisplayName, e.GameData.Viking.Uid, e.GameData.DatePlayed, false, false, e.DailyValue) ).Take(count).ToList(); else selectedData = query.Select(e => new GameDataResponse( - e.DailyScore.Viking.Name, e.DailyScore.Viking.Uid, e.DatePlayed, false, false, e.Value) + e.GameData.Viking.Name, e.GameData.Viking.Uid, e.GameData.DatePlayed, false, false, e.DailyValue) ).Take(count).ToList(); return GetSummaryFromResponse(viking, isMultiplayer, difficulty, gameLevel, key, selectedData); @@ -175,36 +167,23 @@ public class GameDataService { return gameData; } - private void SavePairs(Model.GameData gameData, DailyHighscore daily, string xmlDocumentData) { + private void SavePairs(Model.GameData gameData, string xmlDocumentData) { foreach (var pair in GetGameDataPairs(xmlDocumentData)) { GameDataPair? dbPair = gameData.GameDataPairs.FirstOrDefault(x => x.Name == pair.Name); - if (dbPair == null) - gameData.GameDataPairs.Add(pair); - else if (pair.Name == "time" && dbPair.Value > pair.Value) - dbPair.Value = pair.Value; - else if (pair.Name != "time" && dbPair.Value <= pair.Value) - dbPair.Value = pair.Value; - DailyHighscorePair? dailyPair = daily.ScorePairs.FirstOrDefault(x => x.Name == pair.Name); - if (dailyPair == null) { - daily.Difficulty = gameData.Difficulty; - daily.GameLevel = gameData.GameLevel; - dailyPair = new DailyHighscorePair { - Name = pair.Name, - Value = pair.Value, - DatePlayed = DateTime.Today - }; - daily.ScorePairs.Add(dailyPair); - } else if ( - (pair.Name == "time" && dailyPair.Value > pair.Value) || // Better Time - (pair.Name != "time" && dailyPair.Value <= pair.Value) || // Better Score - dailyPair.DatePlayed != DateTime.Today // Another Day - ) { - daily.Difficulty = gameData.Difficulty; - daily.GameLevel = gameData.GameLevel; - dailyPair.DatePlayed = DateTime.Today; - dailyPair.Value = pair.Value; - } + // If Name == "time" then (existing <= incoming) needs to be false (effectively (existing > incoming), as time should function). + // if Name is anything else, then second condition as normal. + bool newBest = (dbPair == null) || ((pair.Name == "time") != (dbPair.Value <= pair.Value)); + + if (dbPair == null) { + gameData.GameDataPairs.Add(pair); + dbPair = pair; + } else if (newBest) dbPair.Value = pair.Value; + + if ( + newBest || // Surpassed Score (or Unset) + gameData.DatePlayed.Date != DateTime.UtcNow.Date // Another Day + ) dbPair.DailyValue = pair.Value; } } From 7d148ce38116767aeb448abda9caeac9eae85ab4 Mon Sep 17 00:00:00 2001 From: Hipposgrumm Date: Mon, 30 Jun 2025 21:02:47 -0600 Subject: [PATCH 4/5] This is why I don't like having to resolve merge conflicts because I don't know what I'm doing. --- src/Controllers/Common/ContentController.cs | 2 +- src/Model/GameDataPair.cs | 1 - src/Services/GameDataService.cs | 49 +++------------------ 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 08168c6..2c52423 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -2126,7 +2126,7 @@ public class ContentController : Controller { [Route("ContentWebService.asmx/GetPeriodicGameDataByGame")] // used by Math Blaster and WoJS (probably from 24 hours ago to now) [VikingSession(UseLock = true)] public IActionResult GetPeriodicGameDataByGame(Viking viking, [FromForm] int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, int score, bool buddyFilter, string apiKey) { - return Ok(gameDataService.GetDailyGameData(viking, gameId, isMultiplayer, difficulty, gameLevel, key, count, AscendingOrder, buddyFilter, apiKey)); + return Ok(gameDataService.GetGameData(viking, gameId, isMultiplayer, difficulty, gameLevel, key, count, AscendingOrder, buddyFilter, apiKey, DateTime.Now.AddHours(-24), DateTime.Now)); } [HttpPost] diff --git a/src/Model/GameDataPair.cs b/src/Model/GameDataPair.cs index 7e029e5..9543936 100644 --- a/src/Model/GameDataPair.cs +++ b/src/Model/GameDataPair.cs @@ -7,6 +7,5 @@ public class GameDataPair { public int GameDataId { get; set; } public string Name { get; set; } = null!; public int Value { get; set; } - public int DailyValue { get; set; } public virtual GameData GameData { get; set; } = null!; } diff --git a/src/Services/GameDataService.cs b/src/Services/GameDataService.cs index 2faa29a..cd18f2d 100644 --- a/src/Services/GameDataService.cs +++ b/src/Services/GameDataService.cs @@ -31,9 +31,9 @@ public class GameDataService { viking.GameData.Add(gameData); } - - SavePairs(gameData, xmlDocumentData); gameData.DatePlayed = DateTime.UtcNow; + SavePairs(gameData, xmlDocumentData); + ctx.SaveChanges(); return true; @@ -72,33 +72,6 @@ public class GameDataService { return GetSummaryFromResponse(viking, isMultiplayer, difficulty, gameLevel, key, selectedData); } - - public GameDataSummary GetDailyGameData(Viking viking, int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, bool buddyFilter, string apiKey) { - IQueryable query = ctx.GameData - .Where(x => - x.GameId == gameId && x.IsMultiplayer == false && - x.Difficulty == difficulty && x.GameLevel == gameLevel && - x.DatePlayed.Date == DateTime.UtcNow.Date - ).SelectMany(e => e.GameDataPairs).Where(x => x.Name == key); - - // TODO: Buddy filter - - if (AscendingOrder) query = query.OrderBy(e => e.Value); - else query = query.OrderByDescending(e => e.Value); - - List selectedData; - if (ClientVersion.GetVersion(apiKey) <= ClientVersion.Max_OldJS) - // use DisplayName instead of Name - selectedData = query.Select(e => new GameDataResponse( - XmlUtil.DeserializeXml(e.GameData.Viking.AvatarSerialized).DisplayName, e.GameData.Viking.Uid, e.GameData.DatePlayed, false, false, e.DailyValue) - ).Take(count).ToList(); - else - selectedData = query.Select(e => new GameDataResponse( - e.GameData.Viking.Name, e.GameData.Viking.Uid, e.GameData.DatePlayed, false, false, e.DailyValue) - ).Take(count).ToList(); - - return GetSummaryFromResponse(viking, isMultiplayer, difficulty, gameLevel, key, selectedData); - } // ByUser for JumpStart's My Scores public GameDataSummary GetGameDataByUser(Viking viking, int gameId, bool isMultiplayer, int difficulty, int gameLevel, string key, int count, bool AscendingOrder, string apiKey) { @@ -170,20 +143,12 @@ public class GameDataService { private void SavePairs(Model.GameData gameData, string xmlDocumentData) { foreach (var pair in GetGameDataPairs(xmlDocumentData)) { GameDataPair? dbPair = gameData.GameDataPairs.FirstOrDefault(x => x.Name == pair.Name); - - // If Name == "time" then (existing <= incoming) needs to be false (effectively (existing > incoming), as time should function). - // if Name is anything else, then second condition as normal. - bool newBest = (dbPair == null) || ((pair.Name == "time") != (dbPair.Value <= pair.Value)); - - if (dbPair == null) { + if (dbPair == null) gameData.GameDataPairs.Add(pair); - dbPair = pair; - } else if (newBest) dbPair.Value = pair.Value; - - if ( - newBest || // Surpassed Score (or Unset) - gameData.DatePlayed.Date != DateTime.UtcNow.Date // Another Day - ) dbPair.DailyValue = pair.Value; + else if (pair.Name == "time" && dbPair.Value > pair.Value) + dbPair.Value = pair.Value; + else if (pair.Name != "time" && dbPair.Value <= pair.Value) + dbPair.Value = pair.Value; } } From 8905d84bc6fe619f21507b1fad472a6f4e843235 Mon Sep 17 00:00:00 2001 From: Hipposgrumm Date: Mon, 30 Jun 2025 21:04:13 -0600 Subject: [PATCH 5/5] :mike_wazouski: --- src/Services/GameDataService.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Services/GameDataService.cs b/src/Services/GameDataService.cs index cd18f2d..8814586 100644 --- a/src/Services/GameDataService.cs +++ b/src/Services/GameDataService.cs @@ -33,9 +33,7 @@ public class GameDataService { } gameData.DatePlayed = DateTime.UtcNow; SavePairs(gameData, xmlDocumentData); - ctx.SaveChanges(); - return true; }