From cd926a8415c65843159ffcdebe8a0e55d1c02c4c Mon Sep 17 00:00:00 2001 From: Slendy Date: Wed, 31 May 2023 20:35:39 -0500 Subject: [PATCH] Refactor LBP3 text search to use the category system --- .../Controllers/Slots/CategoryController.cs | 10 ++++++--- .../Controllers/Slots/SearchController.cs | 4 ---- .../Types/Categories/CategoryHelper.cs | 1 + .../Types/Categories/TextSearchCategory.cs | 22 +++++++++++++++++++ .../Serialization/CustomXmlSerializer.cs | 5 +++-- .../Serialization/CategoryListResponse.cs | 5 +++-- .../Types/Serialization/GameCategory.cs | 8 +++++-- .../Types/Serialization/GameUser.cs | 4 +--- .../Types/Serialization/GameUserSlot.cs | 8 +++++-- .../Types/Serialization/SlotBase.cs | 4 ++-- .../Types/Serialization/TextSearch.cs | 10 --------- 11 files changed, 51 insertions(+), 30 deletions(-) create mode 100644 ProjectLighthouse.Servers.GameServer/Types/Categories/TextSearchCategory.cs delete mode 100644 ProjectLighthouse/Types/Serialization/TextSearch.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/CategoryController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/CategoryController.cs index cfc3752f..60ac1c58 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/CategoryController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/CategoryController.cs @@ -43,7 +43,7 @@ public class CategoryController : ControllerBase PaginationData pageData = this.Request.GetPaginationData(); - pageData.TotalElements = CategoryHelper.Categories.Count; + pageData.TotalElements = CategoryHelper.Categories.Count(c => !string.IsNullOrWhiteSpace(c.Name)); if (!int.TryParse(this.Request.Query["num_categories_with_results"], out int results)) results = 5; @@ -51,7 +51,8 @@ public class CategoryController : ControllerBase SlotQueryBuilder queryBuilder = this.FilterFromRequest(token); - foreach (Category category in CategoryHelper.Categories.Skip(Math.Max(0, pageData.PageStart - 1)) + foreach (Category category in CategoryHelper.Categories.Where(c => !string.IsNullOrWhiteSpace(c.Name)) + .Skip(Math.Max(0, pageData.PageStart - 1)) .Take(Math.Min(pageData.PageSize, pageData.MaxElements)) .ToList()) { @@ -60,7 +61,10 @@ public class CategoryController : ControllerBase results--; } - return this.Ok(new CategoryListResponse(categories, pageData.TotalElements, "", pageData.HintStart)); + Category searchCategory = CategoryHelper.Categories.First(c => c.Tag == "text"); + GameCategory gameSearchCategory = GameCategory.CreateFromEntity(searchCategory, null); + + return this.Ok(new CategoryListResponse(categories, gameSearchCategory, pageData.TotalElements, "", pageData.HintStart)); } [HttpGet("searches/{endpointName}")] diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SearchController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SearchController.cs index b4eb935c..b67e507a 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SearchController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SearchController.cs @@ -26,10 +26,6 @@ public class SearchController : ControllerBase this.database = database; } - [HttpGet("searchLBP3")] - public Task SearchSlotsLBP3([FromQuery] string textFilter) - => this.SearchSlots(textFilter, "results"); - [HttpGet("search")] public async Task SearchSlots([FromQuery] string query, string? keyName = "slots") { diff --git a/ProjectLighthouse.Servers.GameServer/Types/Categories/CategoryHelper.cs b/ProjectLighthouse.Servers.GameServer/Types/Categories/CategoryHelper.cs index 404e458e..c4bfc5fd 100644 --- a/ProjectLighthouse.Servers.GameServer/Types/Categories/CategoryHelper.cs +++ b/ProjectLighthouse.Servers.GameServer/Types/Categories/CategoryHelper.cs @@ -20,6 +20,7 @@ public static class CategoryHelper Categories.Add(new QueueCategory()); Categories.Add(new HeartedCategory()); Categories.Add(new LuckyDipCategory()); + Categories.Add(new TextSearchCategory()); using DatabaseContext database = DatabaseContext.CreateNewInstance(); foreach (DatabaseCategoryEntity category in database.CustomCategories) Categories.Add(new CustomCategory(category)); diff --git a/ProjectLighthouse.Servers.GameServer/Types/Categories/TextSearchCategory.cs b/ProjectLighthouse.Servers.GameServer/Types/Categories/TextSearchCategory.cs new file mode 100644 index 00000000..459e4af5 --- /dev/null +++ b/ProjectLighthouse.Servers.GameServer/Types/Categories/TextSearchCategory.cs @@ -0,0 +1,22 @@ +using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Extensions; +using LBPUnion.ProjectLighthouse.Filter; +using LBPUnion.ProjectLighthouse.Filter.Sorts; +using LBPUnion.ProjectLighthouse.Types.Entities.Level; +using LBPUnion.ProjectLighthouse.Types.Entities.Token; + +namespace LBPUnion.ProjectLighthouse.Servers.GameServer.Types.Categories; + +public class TextSearchCategory : SlotCategory +{ + public override string Name { get; set; } = ""; + public override string Description { get; set; } = ""; + public override string IconHash { get; set; } = ""; + public override string Endpoint { get; set; } = "text"; + public override string Tag => "text"; + + public override IQueryable GetItems + (DatabaseContext database, GameTokenEntity token, SlotQueryBuilder queryBuilder) => + database.Slots.Where(queryBuilder.Build()) + .ApplyOrdering(new SlotSortBuilder().AddSort(new TotalPlaysSort())); +} \ No newline at end of file diff --git a/ProjectLighthouse/Serialization/CustomXmlSerializer.cs b/ProjectLighthouse/Serialization/CustomXmlSerializer.cs index d43ba15e..9ce10e5d 100644 --- a/ProjectLighthouse/Serialization/CustomXmlSerializer.cs +++ b/ProjectLighthouse/Serialization/CustomXmlSerializer.cs @@ -91,8 +91,9 @@ public class CustomXmlSerializer : XmlSerializer } } - // Otherwise if the object isn't a ILbpSerializable, skip - else if (!typeof(ILbpSerializable).IsAssignableFrom(propertyInfo.PropertyType)) + // Otherwise if the object isn't a ILbpSerializable or a nullable ILbpSerializable, skip + else if (!typeof(ILbpSerializable).IsAssignableFrom(propertyInfo.PropertyType) && + !typeof(ILbpSerializable).IsAssignableFrom(Nullable.GetUnderlyingType(propertyInfo.PropertyType))) { continue; } diff --git a/ProjectLighthouse/Types/Serialization/CategoryListResponse.cs b/ProjectLighthouse/Types/Serialization/CategoryListResponse.cs index 5a8715f1..904fb290 100644 --- a/ProjectLighthouse/Types/Serialization/CategoryListResponse.cs +++ b/ProjectLighthouse/Types/Serialization/CategoryListResponse.cs @@ -8,9 +8,10 @@ public class CategoryListResponse : ILbpSerializable { public CategoryListResponse() { } - public CategoryListResponse(List categories, int total, string hint, int hintStart) + public CategoryListResponse(List categories, GameCategory textSearch, int total, string hint, int hintStart) { this.Categories = categories; + this.Search = textSearch; this.Total = total; this.Hint = hint; this.HintStart = hintStart; @@ -26,7 +27,7 @@ public class CategoryListResponse : ILbpSerializable public int HintStart { get; set; } [XmlElement("text_search")] - public TextSearch Search { get; set; } = new(); + public GameCategory Search { get; set; } [XmlElement("category")] public List Categories { get; set; } diff --git a/ProjectLighthouse/Types/Serialization/GameCategory.cs b/ProjectLighthouse/Types/Serialization/GameCategory.cs index 37037069..e097de97 100644 --- a/ProjectLighthouse/Types/Serialization/GameCategory.cs +++ b/ProjectLighthouse/Types/Serialization/GameCategory.cs @@ -8,15 +8,18 @@ namespace LBPUnion.ProjectLighthouse.Types.Serialization; public class GameCategory : ILbpSerializable { [XmlElement("name")] + [DefaultValue("")] public string Name { get; set; } [XmlElement("description")] + [DefaultValue("")] public string Description { get; set; } [XmlElement("url")] public string Url { get; set; } [XmlElement("icon")] + [DefaultValue("")] public string Icon { get; set; } [DefaultValue("")] @@ -32,10 +35,11 @@ public class GameCategory : ILbpSerializable [XmlElement("tag")] public string Tag { get; set; } + [DefaultValue(null)] [XmlElement("results")] - public GenericSerializableList Results { get; set; } + public GenericSerializableList? Results { get; set; } - public static GameCategory CreateFromEntity(Category category, GenericSerializableList results) => + public static GameCategory CreateFromEntity(Category category, GenericSerializableList? results) => new() { Name = category.Name, diff --git a/ProjectLighthouse/Types/Serialization/GameUser.cs b/ProjectLighthouse/Types/Serialization/GameUser.cs index 07cc2b32..885cf61e 100644 --- a/ProjectLighthouse/Types/Serialization/GameUser.cs +++ b/ProjectLighthouse/Types/Serialization/GameUser.cs @@ -165,7 +165,6 @@ public class GameUser : ILbpSerializable, INeedsPreparationForSerialization var stats = await database.Users.Where(u => u.UserId == this.UserId) .Select(_ => new { - Username = database.Users.Where(u => u.UserId == this.UserId).Select(u => u.Username).First(), BonusSlots = database.Users.Where(u => u.UserId == this.UserId).Select(u => u.AdminGrantedSlots).First(), PlaylistCount = database.Playlists.Count(p => p.CreatorId == this.UserId), ReviewCount = database.Reviews.Count(r => r.ReviewerId == this.UserId), @@ -182,7 +181,6 @@ public class GameUser : ILbpSerializable, INeedsPreparationForSerialization .OrderBy(_ => 1) .FirstAsync(); - this.UserHandle.Username = stats.Username; this.CommentsEnabled = this.CommentsEnabled && ServerConfiguration.Instance.UserGeneratedContentLimits.ProfileCommentsEnabled; int entitledSlots = ServerConfiguration.Instance.UserGeneratedContentLimits.EntitledSlots + stats.BonusSlots; @@ -236,7 +234,7 @@ public class GameUser : ILbpSerializable, INeedsPreparationForSerialization new() { UserId = entity.UserId, - UserHandle = new NpHandle("", entity.IconHash), + UserHandle = new NpHandle(entity.Username, entity.IconHash), Biography = entity.Biography, Location = entity.Location, ProfilePins = entity.Pins, diff --git a/ProjectLighthouse/Types/Serialization/GameUserSlot.cs b/ProjectLighthouse/Types/Serialization/GameUserSlot.cs index 6e3d902a..ffa14856 100644 --- a/ProjectLighthouse/Types/Serialization/GameUserSlot.cs +++ b/ProjectLighthouse/Types/Serialization/GameUserSlot.cs @@ -245,12 +245,16 @@ public class GameUserSlot : SlotBase, INeedsPreparationForSerialization PhotoCount = database.Photos.Count(p => p.SlotId == this.SlotId), AuthorPhotoCount = database.Photos.Count(p => p.SlotId == this.SlotId && p.CreatorId == this.CreatorId), HeartCount = database.HeartedLevels.Count(h => h.SlotId == this.SlotId), - Username = database.Users.Where(u => u.UserId == this.CreatorId).Select(u => u.Username).First(), + AuthorHandle = database.Users.Where(u => u.UserId == this.CreatorId).Select(u => new NpHandle + { + Username = u.Username, + IconHash = u.IconHash, + }).First(), }) .OrderBy(_ => 1) .FirstAsync(); ReflectionHelper.CopyAllFields(stats, this); - this.AuthorHandle = new NpHandle(stats.Username, ""); + this.AuthorHandle = stats.AuthorHandle; if (this.GameVersion == GameVersion.LittleBigPlanet1) { diff --git a/ProjectLighthouse/Types/Serialization/SlotBase.cs b/ProjectLighthouse/Types/Serialization/SlotBase.cs index 04377530..ea22a5c7 100644 --- a/ProjectLighthouse/Types/Serialization/SlotBase.cs +++ b/ProjectLighthouse/Types/Serialization/SlotBase.cs @@ -28,7 +28,7 @@ public abstract class SlotBase : ILbpSerializable Description = slot.Description, Location = slot.Location, IconHash = slot.IconHash, - BackgroundHash = slot.BackgroundHash ?? "", + BackgroundHash = slot.BackgroundHash, AuthorLabels = slot.AuthorLabels, GameVersion = slot.GameVersion, Shareable = slot.IsShareable, @@ -49,7 +49,7 @@ public abstract class SlotBase : ILbpSerializable public static SlotBase CreateFromEntity(SlotEntity slot, GameTokenEntity token) => CreateFromEntity(slot, token.GameVersion, token.UserId); - public static SlotBase CreateFromEntity(SlotEntity slot, GameVersion targetGame, int targetUserId) + private static SlotBase CreateFromEntity(SlotEntity slot, GameVersion targetGame, int targetUserId) { if (slot == null) { diff --git a/ProjectLighthouse/Types/Serialization/TextSearch.cs b/ProjectLighthouse/Types/Serialization/TextSearch.cs deleted file mode 100644 index 93dd7ae0..00000000 --- a/ProjectLighthouse/Types/Serialization/TextSearch.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Xml.Serialization; - -namespace LBPUnion.ProjectLighthouse.Types.Serialization; - -[XmlRoot("text_search")] -public class TextSearch -{ - [XmlElement("url")] - public string Url { get; set; } = "/slots/searchLBP3"; -} \ No newline at end of file