From c8fb677b5c88fcaf0129d72a1a453c8ff098fdc9 Mon Sep 17 00:00:00 2001 From: snixtho Date: Wed, 21 Aug 2024 16:34:01 +0200 Subject: [PATCH 1/2] Include author nickname when adding a map to the database. --- .../Services/IPlayerManagerService.cs | 9 +++ src/EvoSC.Common/Services/MapService.cs | 68 +++++++++++++++++-- .../Services/PlayerManagerService.cs | 6 +- 3 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/EvoSC.Common/Interfaces/Services/IPlayerManagerService.cs b/src/EvoSC.Common/Interfaces/Services/IPlayerManagerService.cs index b676ab372..493c6a9c9 100644 --- a/src/EvoSC.Common/Interfaces/Services/IPlayerManagerService.cs +++ b/src/EvoSC.Common/Interfaces/Services/IPlayerManagerService.cs @@ -19,6 +19,15 @@ public interface IPlayerManagerService /// public Task GetOrCreatePlayerAsync(string accountId); + /// + /// Get a player by their account ID. If the player does not + /// exist in the database, create the entry. + /// + /// Account ID of the player. + /// Name of the new player if created. + /// + public Task GetOrCreatePlayerAsync(string accountId, string? name); + /// /// Create a new entry for a player in the database. /// diff --git a/src/EvoSC.Common/Services/MapService.cs b/src/EvoSC.Common/Services/MapService.cs index 05cfad607..e1f957807 100644 --- a/src/EvoSC.Common/Services/MapService.cs +++ b/src/EvoSC.Common/Services/MapService.cs @@ -6,6 +6,10 @@ using EvoSC.Common.Interfaces.Services; using EvoSC.Common.Models.Maps; using EvoSC.Common.Util; +using GbxRemoteNet; +using GbxRemoteNet.Interfaces; +using GbxRemoteNet.Structs; +using GbxRemoteNet.XmlRpc.ExtraTypes; using Microsoft.Extensions.Logging; namespace EvoSC.Common.Services; @@ -85,9 +89,9 @@ public async Task RemoveMapAsync(long mapId) public async Task AddCurrentMapListAsync() { - var serverMapList = await serverClient.Remote.GetMapListAsync(-1, 0); + var maplist = await GetRemoteMapListAsync(); - foreach (var serverMap in serverMapList) + foreach (var serverMap in maplist) { try { @@ -97,9 +101,9 @@ public async Task AddCurrentMapListAsync() { continue; } - + var authorAccountId = PlayerUtils.ConvertLoginToAccountId(serverMap.Author); - var author = await playerService.GetOrCreatePlayerAsync(authorAccountId); + var author = await playerService.GetOrCreatePlayerAsync(authorAccountId, serverMap.AuthorNickname); var mapMeta = new MapMetadata { @@ -115,7 +119,7 @@ public async Task AddCurrentMapListAsync() logger.LogDebug("Adding map {Name} ({Uid}) to the database", serverMap.Name, serverMap.UId); var map = await mapRepository.AddMapAsync(mapMeta, author, serverMap.FileName); - var mapDetails = await FetchMapDetailsAsync(map); + var mapDetails = new ParsedMap(serverMap, map); await mapRepository.AddMapDetailsAsync(mapDetails, map); } catch (Exception ex) @@ -137,8 +141,8 @@ public async Task GetOrAddCurrentMapAsync() return map; } - var mapAuthor = - await playerService.GetOrCreatePlayerAsync(PlayerUtils.ConvertLoginToAccountId(currentMap.Author)); + var authorAccountId = PlayerUtils.ConvertLoginToAccountId(currentMap.Author); + var mapAuthor = await playerService.GetOrCreatePlayerAsync(authorAccountId, currentMap.AuthorNickname); var mapMeta = new MapMetadata { @@ -235,4 +239,54 @@ private async Task SaveMapFileAsync(Stream mapStream, string filePath) throw; } } + + private async Task> GetRemoteMapListAsync() + { + var serverMapList = await serverClient.Remote.GetMapListAsync(-1, 0); + var calls = new List(); + + // server can have more maps than calls allowed in a multicall, so split it up + for (var i = 0; i < serverMapList.Length; i++) + { + if (i % 20 == 0) + { + calls.Add(new MultiCall()); + } + + calls.Last().Add("GetMapInfo", serverMapList[i].FileName); + } + + var maplist = new List(); + + foreach (var call in calls) + { + var mapsWithDetails = await serverClient.Remote.MultiCallAsync(call); + + foreach (GbxDynamicObject serverMap in mapsWithDetails) + { + maplist.Add(new TmMapInfo + { + UId = (string)serverMap["UId"], + Name = (string)serverMap["Name"], + FileName = (string)serverMap["FileName"], + Author = (string)serverMap["Author"], + AuthorNickname = (string)serverMap["AuthorNickname"], + Environnement = (string)serverMap["Environnement"], + Mood = (string)serverMap["Mood"], + BronzeTime = (int)serverMap["BronzeTime"], + SilverTime = (int)serverMap["SilverTime"], + GoldTime = (int)serverMap["GoldTime"], + AuthorTime = (int)serverMap["AuthorTime"], + CopperPrice = (int)serverMap["CopperPrice"], + LapRace = (bool)serverMap["LapRace"], + NbLaps = (int)serverMap["NbLaps"], + NbCheckpoints = (int)serverMap["NbCheckpoints"], + MapType = (string)serverMap["MapType"], + MapStyle = (string)serverMap["MapStyle"] + }); + } + } + + return maplist; + } } diff --git a/src/EvoSC.Common/Services/PlayerManagerService.cs b/src/EvoSC.Common/Services/PlayerManagerService.cs index 325fe73fd..57f8f5192 100644 --- a/src/EvoSC.Common/Services/PlayerManagerService.cs +++ b/src/EvoSC.Common/Services/PlayerManagerService.cs @@ -16,7 +16,9 @@ public class PlayerManagerService(IPlayerRepository playerRepository, IPlayerCac public async Task GetPlayerAsync(string accountId) => await playerRepository.GetPlayerByAccountIdAsync(accountId); - public async Task GetOrCreatePlayerAsync(string accountId) + public Task GetOrCreatePlayerAsync(string accountId) => GetOrCreatePlayerAsync(accountId, null); + + public async Task GetOrCreatePlayerAsync(string accountId, string? name) { try { @@ -34,7 +36,7 @@ public async Task GetOrCreatePlayerAsync(string accountId) accountId); } - return await CreatePlayerAsync(accountId); + return await CreatePlayerAsync(accountId, name); } public Task CreatePlayerAsync(string accountId) => CreatePlayerAsync(accountId, null); From 6089b54331d71453e0ee13cca44130e93fbbd084 Mon Sep 17 00:00:00 2001 From: snixtho Date: Wed, 21 Aug 2024 16:58:02 +0200 Subject: [PATCH 2/2] fix tests --- .../Services/MapServiceTests.cs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/EvoSC.Common.Tests/Services/MapServiceTests.cs b/tests/EvoSC.Common.Tests/Services/MapServiceTests.cs index bc05ed42d..fc2ca4cbe 100644 --- a/tests/EvoSC.Common.Tests/Services/MapServiceTests.cs +++ b/tests/EvoSC.Common.Tests/Services/MapServiceTests.cs @@ -14,8 +14,10 @@ using EvoSC.Common.Models.Maps; using EvoSC.Common.Services; using EvoSC.Testing; +using GbxRemoteNet; using GbxRemoteNet.Interfaces; using GbxRemoteNet.Structs; +using GbxRemoteNet.XmlRpc.ExtraTypes; using Microsoft.Extensions.Logging; using Moq; using Xunit; @@ -370,6 +372,7 @@ public async Task Add_Current_Map_List_Adds_Maplist() { Name = "snippens dream", Author = "0efeba8a-9cda-49fa-ab25-35f1d9218c95", + AuthorNickname = "snippen", AuthorTime = 1337, BronzeTime = 1337, CopperPrice = 1337, @@ -388,10 +391,32 @@ public async Task Add_Current_Map_List_Adds_Maplist() UpdatedAt = new DateTime(), LastVisit = new DateTime() }; - _server.Remote.Setup(r => r.GetMapListAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(new[] { tmMapInfo })); - _playerService.Setup(p => p.GetOrCreatePlayerAsync(It.IsAny())) + _server.Remote.Setup(r => r.MultiCallAsync(It.IsAny())) + .ReturnsAsync([ + new GbxDynamicObject() + { + { "UId", tmMapInfo.UId }, + { "Name", tmMapInfo.Name }, + { "FileName", tmMapInfo.FileName }, + { "Author", tmMapInfo.Author }, + { "AuthorNickname", tmMapInfo.AuthorNickname }, + { "Environnement", tmMapInfo.Environnement }, + { "Mood", tmMapInfo.Mood }, + { "BronzeTime", tmMapInfo.BronzeTime }, + { "SilverTime", tmMapInfo.SilverTime }, + { "GoldTime", tmMapInfo.GoldTime }, + { "AuthorTime", tmMapInfo.AuthorTime }, + { "CopperPrice", tmMapInfo.CopperPrice }, + { "LapRace", tmMapInfo.LapRace }, + { "NbLaps", tmMapInfo.NbLaps }, + { "NbCheckpoints", tmMapInfo.NbCheckpoints }, + { "MapType", tmMapInfo.MapType }, + { "MapStyle", tmMapInfo.MapStyle } + } + ]); + _playerService.Setup(p => p.GetOrCreatePlayerAsync(It.IsAny(), "snippen")) .Returns(Task.FromResult((IPlayer)player)); await _mapService.AddCurrentMapListAsync(); @@ -407,6 +432,7 @@ public async Task Get_Or_Add_Current_Map_Returns_Current_Map() { Name = "snippens track", Author = "0efeba8a-9cda-49fa-ab25-35f1d9218c95", + AuthorNickname = "snippen", AuthorTime = 1337, BronzeTime = 1337, CopperPrice = 1337, @@ -452,7 +478,7 @@ public async Task Get_Or_Add_Current_Map_Returns_Current_Map() .Returns(Task.FromResult((IMap?)null)); _mapRepository.Setup(m => m.AddMapAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult((IMap)map)); - _playerService.Setup(p => p.GetOrCreatePlayerAsync(It.IsAny())) + _playerService.Setup(p => p.GetOrCreatePlayerAsync(It.IsAny(), "snippen")) .Returns(Task.FromResult((IPlayer)player)); var retrievedMap = await _mapService.GetOrAddCurrentMapAsync();