From c3db1d278cfde990b9ea32f36ac0de1ef52584be Mon Sep 17 00:00:00 2001 From: jvyden Date: Thu, 19 Oct 2023 18:59:50 -0400 Subject: [PATCH 1/9] Fix serialization of !DeletedUser --- .../DataTypes/Response/GameUserResponse.cs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Refresh.GameServer/Endpoints/Game/DataTypes/Response/GameUserResponse.cs b/Refresh.GameServer/Endpoints/Game/DataTypes/Response/GameUserResponse.cs index 58ac21ef..1aec485f 100644 --- a/Refresh.GameServer/Endpoints/Game/DataTypes/Response/GameUserResponse.cs +++ b/Refresh.GameServer/Endpoints/Game/DataTypes/Response/GameUserResponse.cs @@ -75,12 +75,12 @@ public class GameUserResponse : IDataConvertableFrom Handle = SerializedUserHandle.FromUser(old), CommentCount = old.ProfileComments.Count, CommentsEnabled = true, - FavouriteLevelCount = old.FavouriteLevelRelations.Count(), - FavouriteUserCount = old.UsersFavourited.Count(), - QueuedLevelCount = old.QueueLevelRelations.Count(), - HeartCount = old.UsersFavouritingMe.Count(), - PhotosByMeCount = old.PhotosByMe.Count(), - PhotosWithMeCount = old.PhotosWithMe.Count(), + FavouriteLevelCount = old.IsManaged ? old.FavouriteLevelRelations.Count() : 0, + FavouriteUserCount = old.IsManaged ? old.UsersFavourited.Count() : 0, + QueuedLevelCount = old.IsManaged ? old.QueueLevelRelations.Count() : 0, + HeartCount = old.IsManaged ? old.UsersFavouritingMe.Count() : 0, + PhotosByMeCount = old.IsManaged ? old.PhotosByMe.Count() : 0, + PhotosWithMeCount = old.IsManaged ? old.PhotosWithMe.Count() : 0, EntitledSlots = MaximumLevels, EntitledSlotsLBP2 = MaximumLevels, @@ -102,6 +102,14 @@ public static IEnumerable FromOldListWithExtraData(IEnumerable private void FillInExtraData(GameUser old, TokenGame gameVersion, GameDatabaseContext database) { + if (!old.IsManaged) + { + this.PlanetsHash = "0"; + this.IconHash = "0"; + + return; + } + this.PlanetsHash = gameVersion switch { TokenGame.LittleBigPlanet1 => "0", From b78b586bb35dd4a386b0794baf0cc4b6ddd548b8 Mon Sep 17 00:00:00 2001 From: jvyden Date: Thu, 19 Oct 2023 19:24:13 -0400 Subject: [PATCH 2/9] Add theoretical support for overriding level lists --- .../Endpoints/Game/Levels/LevelEndpoints.cs | 41 ++++++++++++++++--- Refresh.GameServer/RefreshGameServer.cs | 3 +- .../Services/LevelListOverrideService.cs | 37 +++++++++++++++++ .../GameServer/TestRefreshGameServer.cs | 1 + 4 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 Refresh.GameServer/Services/LevelListOverrideService.cs diff --git a/Refresh.GameServer/Endpoints/Game/Levels/LevelEndpoints.cs b/Refresh.GameServer/Endpoints/Game/Levels/LevelEndpoints.cs index a70a3c72..d66b6d24 100644 --- a/Refresh.GameServer/Endpoints/Game/Levels/LevelEndpoints.cs +++ b/Refresh.GameServer/Endpoints/Game/Levels/LevelEndpoints.cs @@ -22,10 +22,20 @@ public class LevelEndpoints : EndpointGroup GameDatabaseContext database, CategoryService categoryService, MatchService matchService, + LevelListOverrideService overrideService, GameUser user, Token token, string route) { + if (overrideService.UserHasOverrides(user)) + { + List overrides = overrideService.GetOverridesForUser(user, database) + .Select(l => GameMinimalLevelResponse.FromOldWithExtraData(l, matchService)) + .ToList()!; + + return new SerializedMinimalLevelList(overrides, overrides.Count); + } + (int skip, int count) = context.GetPageData(); DatabaseList? levels = categoryService.Categories @@ -43,12 +53,19 @@ public class LevelEndpoints : EndpointGroup [GameEndpoint("slots/{route}/{username}", ContentType.Xml)] [MinimumRole(GameUserRole.Restricted)] [NullStatusCode(NotFound)] - public SerializedMinimalLevelList? GetLevelsWithPlayer(RequestContext context, GameDatabaseContext database, CategoryService categories, MatchService matchService, Token token, string route, string username) + public SerializedMinimalLevelList? GetLevelsWithPlayer(RequestContext context, + GameDatabaseContext database, + CategoryService categories, + MatchService matchService, + LevelListOverrideService overrideService, + Token token, + string route, + string username) { GameUser? user = database.GetUserByUsername(username); if (user == null) return null; - return this.GetLevels(context, database, categories, matchService, user, token, route); + return this.GetLevels(context, database, categories, matchService, overrideService, user, token, route); } [GameEndpoint("s/user/{id}", ContentType.Xml)] @@ -118,18 +135,30 @@ public SerializedMinimalLevelResultsList GetLevelsFromCategory(RequestContext co [GameEndpoint("slots", ContentType.Xml)] [MinimumRole(GameUserRole.Restricted)] - public SerializedMinimalLevelList? NewestLevels(RequestContext context, GameDatabaseContext database, CategoryService categories, MatchService matchService, GameUser user, Token token) - => this.GetLevels(context, database, categories, matchService, user, token, "newest"); + public SerializedMinimalLevelList? NewestLevels(RequestContext context, + GameDatabaseContext database, + CategoryService categories, + MatchService matchService, + LevelListOverrideService overrideService, + GameUser user, + Token token) + => this.GetLevels(context, database, categories, matchService, overrideService, user, token, "newest"); [GameEndpoint("favouriteSlots/{username}", ContentType.Xml)] [NullStatusCode(NotFound)] [MinimumRole(GameUserRole.Restricted)] - public SerializedMinimalFavouriteLevelList? FavouriteLevels(RequestContext context, GameDatabaseContext database, CategoryService categories, MatchService matchService, Token token, string username) + public SerializedMinimalFavouriteLevelList? FavouriteLevels(RequestContext context, + GameDatabaseContext database, + CategoryService categories, + MatchService matchService, + LevelListOverrideService overrideService, + Token token, + string username) { GameUser? user = database.GetUserByUsername(username); if (user == null) return null; - SerializedMinimalLevelList? levels = this.GetLevels(context, database, categories, matchService, user, token, "favouriteSlots"); + SerializedMinimalLevelList? levels = this.GetLevels(context, database, categories, matchService, overrideService, user, token, "favouriteSlots"); return new SerializedMinimalFavouriteLevelList(levels); } diff --git a/Refresh.GameServer/RefreshGameServer.cs b/Refresh.GameServer/RefreshGameServer.cs index 1cb097d8..848d5634 100644 --- a/Refresh.GameServer/RefreshGameServer.cs +++ b/Refresh.GameServer/RefreshGameServer.cs @@ -10,7 +10,6 @@ using Bunkum.HealthChecks; using Bunkum.HealthChecks.RealmDatabase; using Bunkum.Protocols.Http; -using Bunkum.RealmDatabase; using NotEnoughLogs; using NotEnoughLogs.Behaviour; using NotEnoughLogs.Sinks; @@ -146,6 +145,8 @@ protected virtual void SetupServices() if (this._config!.TrackRequestStatistics) this._server.AddService(); + this._server.AddService(); + #if DEBUG this._server.AddService(); #endif diff --git a/Refresh.GameServer/Services/LevelListOverrideService.cs b/Refresh.GameServer/Services/LevelListOverrideService.cs new file mode 100644 index 00000000..4e8379e2 --- /dev/null +++ b/Refresh.GameServer/Services/LevelListOverrideService.cs @@ -0,0 +1,37 @@ +using System.Diagnostics; +using Bunkum.Core.Services; +using MongoDB.Bson; +using NotEnoughLogs; +using Refresh.GameServer.Database; +using Refresh.GameServer.Types.Levels; +using Refresh.GameServer.Types.UserData; + +namespace Refresh.GameServer.Services; + +public class LevelListOverrideService : EndpointService +{ + public LevelListOverrideService(Logger logger) : base(logger) + {} + + private readonly Dictionary> _userIdsToLevelList = new(1); + + public bool UserHasOverrides(GameUser user) => this._userIdsToLevelList.ContainsKey(user.UserId); + + public void AddOverridesForUser(GameUser user, IEnumerable levels) + { + Debug.Assert(!this.UserHasOverrides(user), "User already has overrides"); + + List ids = levels.Select(l => l.LevelId).ToList(); + this._userIdsToLevelList.Add(user.UserId, ids); + } + + public IEnumerable GetOverridesForUser(GameUser user, GameDatabaseContext database) + { + Debug.Assert(this.UserHasOverrides(user), "User does not have overrides, should be checked first"); + + List overrides = this._userIdsToLevelList[user.UserId]; + this._userIdsToLevelList.Remove(user.UserId); + + return overrides.Select(database.GetLevelById)!; + } +} \ No newline at end of file diff --git a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs index 27298c6f..02d1893a 100644 --- a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs +++ b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs @@ -66,5 +66,6 @@ protected override void SetupServices() this._server.AddService(); this._server.AddService(); this._server.AddService(); + this._server.AddService(); } } \ No newline at end of file From 376fd2b759689a0f33bfd13b36d610a3bd9b6f10 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 20 Oct 2023 17:55:33 -0400 Subject: [PATCH 3/9] Start writing tests for overriding --- Refresh.GameServer/RefreshContext.cs | 1 + .../Services/LevelListOverrideService.cs | 10 +++- .../GameServer/TestRefreshGameServer.cs | 13 +++++ RefreshTests.GameServer/TestContext.cs | 5 ++ .../Tests/Levels/LevelListOverrideTests.cs | 53 +++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 RefreshTests.GameServer/Tests/Levels/LevelListOverrideTests.cs diff --git a/Refresh.GameServer/RefreshContext.cs b/Refresh.GameServer/RefreshContext.cs index 2135ad1b..bec8a4e7 100644 --- a/Refresh.GameServer/RefreshContext.cs +++ b/Refresh.GameServer/RefreshContext.cs @@ -5,4 +5,5 @@ public enum RefreshContext Startup, Worker, Discord, + LevelListOverride, } \ No newline at end of file diff --git a/Refresh.GameServer/Services/LevelListOverrideService.cs b/Refresh.GameServer/Services/LevelListOverrideService.cs index 4e8379e2..051ceb46 100644 --- a/Refresh.GameServer/Services/LevelListOverrideService.cs +++ b/Refresh.GameServer/Services/LevelListOverrideService.cs @@ -15,13 +15,20 @@ public LevelListOverrideService(Logger logger) : base(logger) private readonly Dictionary> _userIdsToLevelList = new(1); - public bool UserHasOverrides(GameUser user) => this._userIdsToLevelList.ContainsKey(user.UserId); + public bool UserHasOverrides(GameUser user) + { + bool result = this._userIdsToLevelList.ContainsKey(user.UserId); + + this.Logger.LogTrace(RefreshContext.LevelListOverride, "{0} has overrides: {1}", user, result); + return result; + } public void AddOverridesForUser(GameUser user, IEnumerable levels) { Debug.Assert(!this.UserHasOverrides(user), "User already has overrides"); List ids = levels.Select(l => l.LevelId).ToList(); + this.Logger.LogDebug(RefreshContext.LevelListOverride, "Adding level override for {0}: [{1}]", user, string.Join(", ", ids)); this._userIdsToLevelList.Add(user.UserId, ids); } @@ -30,6 +37,7 @@ public IEnumerable GetOverridesForUser(GameUser user, GameDatabaseCon Debug.Assert(this.UserHasOverrides(user), "User does not have overrides, should be checked first"); List overrides = this._userIdsToLevelList[user.UserId]; + this.Logger.LogDebug(RefreshContext.LevelListOverride, "Getting level override for {0}: [{1}]", user, string.Join(", ", overrides)); this._userIdsToLevelList.Remove(user.UserId); return overrides.Select(database.GetLevelById)!; diff --git a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs index 02d1893a..d51b62be 100644 --- a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs +++ b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs @@ -1,5 +1,9 @@ +using System.Reflection; +using Bunkum.Core; +using Bunkum.Core.Services; using Bunkum.Core.Storage; using Bunkum.Protocols.Http; +using JetBrains.Annotations; using NotEnoughLogs; using NotEnoughLogs.Behaviour; using NotEnoughLogs.Sinks; @@ -68,4 +72,13 @@ protected override void SetupServices() this._server.AddService(); this._server.AddService(); } + + [Pure] + public TService GetService() where TService : Service + { + List services = (List)typeof(BunkumServer).GetField("_services", BindingFlags.Instance | BindingFlags.NonPublic)! + .GetValue(this._server)!; + + return (TService)services.First(s => typeof(TService) == s.GetType()); + } } \ No newline at end of file diff --git a/RefreshTests.GameServer/TestContext.cs b/RefreshTests.GameServer/TestContext.cs index 320d8a17..fcfc849d 100644 --- a/RefreshTests.GameServer/TestContext.cs +++ b/RefreshTests.GameServer/TestContext.cs @@ -1,4 +1,6 @@ +using Bunkum.Core.Services; using Bunkum.Protocols.Http.Direct; +using JetBrains.Annotations; using Refresh.GameServer.Authentication; using Refresh.GameServer.Database; using Refresh.GameServer.Types; @@ -120,6 +122,9 @@ public GameSubmittedScore SubmitScore(int score, byte type, GameLevel level, Gam return submittedScore; } + [Pure] + public TService GetService() where TService : Service => this.Server.Value.GetService(); + public void Dispose() { this.Database.Dispose(); diff --git a/RefreshTests.GameServer/Tests/Levels/LevelListOverrideTests.cs b/RefreshTests.GameServer/Tests/Levels/LevelListOverrideTests.cs new file mode 100644 index 00000000..dc7fb467 --- /dev/null +++ b/RefreshTests.GameServer/Tests/Levels/LevelListOverrideTests.cs @@ -0,0 +1,53 @@ +using MongoDB.Bson; +using NotEnoughLogs; +using Refresh.GameServer.Authentication; +using Refresh.GameServer.Services; +using Refresh.GameServer.Types.Levels; +using Refresh.GameServer.Types.UserData; +using RefreshTests.GameServer.Logging; + +namespace RefreshTests.GameServer.Tests.Levels; + +public class LevelListOverrideUnitTests +{ + [Test] + public void CanOverrideLevel() + { + using Logger logger = new(new []{ new NUnitSink() }); + LevelListOverrideService service = new(logger); + GameUser user = new() + { + UserId = new ObjectId("64ea5a8a7c412d18ab640fd1"), + Username = "SuperDingus69", + }; + + GameLevel level = new() + { + LevelId = 1, + }; + + service.AddOverridesForUser(user, new []{level}); + } +} + +public class LevelListOverrideIntegrationTests : GameServerTest +{ + [Test] + public void CanGetOverriddenLevels() + { + using TestContext context = this.GetServer(); + GameUser user = context.CreateUser(); + GameLevel level = context.CreateLevel(user, "dingus 2B47430C-70F1-4A21-A1D0-EC3011A62239"); + + using HttpClient client = context.GetAuthenticatedClient(TokenType.Game); + + // Verify that the endpoint isn't already attempting to return anything + // This can be any endpoint that doesnt return all levels but I chose mmpicks + HttpResponseMessage message = client.GetAsync("/lbp/slots/mmpicks").Result; + Assert.That(message.StatusCode, Is.EqualTo(OK)); + Assert.That(message.Content.ReadAsStringAsync().Result, Does.Not.Contain(level.Title)); + + LevelListOverrideService overrideService = context.GetService(); + Assert.That(overrideService.UserHasOverrides(user), Is.False); + } +} \ No newline at end of file From bf6d0480b75263d8fd61b5411d4663794cbebf6f Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 14:54:48 -0400 Subject: [PATCH 4/9] API endpoint for setting an individual level as an override --- .../Endpoints/ApiV3/LevelApiEndpoints.cs | 14 ++++++++++++++ .../Services/LevelListOverrideService.cs | 11 ++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Refresh.GameServer/Endpoints/ApiV3/LevelApiEndpoints.cs b/Refresh.GameServer/Endpoints/ApiV3/LevelApiEndpoints.cs index 7af63040..e51465d8 100644 --- a/Refresh.GameServer/Endpoints/ApiV3/LevelApiEndpoints.cs +++ b/Refresh.GameServer/Endpoints/ApiV3/LevelApiEndpoints.cs @@ -104,4 +104,18 @@ public ApiOkResponse DeleteLevelById(RequestContext context, GameDatabaseContext return new ApiOkResponse(); } + + [ApiV3Endpoint("levels/id/{id}/setAsOverride", HttpMethods.Post)] + [DocSummary("Marks the level to show in the next slot list gotten from the game")] + [DocError(typeof(ApiNotFoundError), ApiNotFoundError.LevelMissingErrorWhen)] + public ApiOkResponse SetLevelAsOverrideById(RequestContext context, GameDatabaseContext database, GameUser user, LevelListOverrideService service, + [DocSummary("The ID of the level")] int id) + { + GameLevel? level = database.GetLevelById(id); + if (level == null) return ApiNotFoundError.LevelMissingError; + + service.AddOverridesForUser(user, level); + + return new ApiOkResponse(); + } } \ No newline at end of file diff --git a/Refresh.GameServer/Services/LevelListOverrideService.cs b/Refresh.GameServer/Services/LevelListOverrideService.cs index 051ceb46..d2360758 100644 --- a/Refresh.GameServer/Services/LevelListOverrideService.cs +++ b/Refresh.GameServer/Services/LevelListOverrideService.cs @@ -19,16 +19,21 @@ public bool UserHasOverrides(GameUser user) { bool result = this._userIdsToLevelList.ContainsKey(user.UserId); - this.Logger.LogTrace(RefreshContext.LevelListOverride, "{0} has overrides: {1}", user, result); + this.Logger.LogTrace(RefreshContext.LevelListOverride, "{0} has overrides: {1}", user.Username, result); return result; } + public void AddOverridesForUser(GameUser user, GameLevel level) + { + this.AddOverridesForUser(user, new[] { level }); + } + public void AddOverridesForUser(GameUser user, IEnumerable levels) { Debug.Assert(!this.UserHasOverrides(user), "User already has overrides"); List ids = levels.Select(l => l.LevelId).ToList(); - this.Logger.LogDebug(RefreshContext.LevelListOverride, "Adding level override for {0}: [{1}]", user, string.Join(", ", ids)); + this.Logger.LogDebug(RefreshContext.LevelListOverride, "Adding level override for {0}: [{1}]", user.Username, string.Join(", ", ids)); this._userIdsToLevelList.Add(user.UserId, ids); } @@ -37,7 +42,7 @@ public IEnumerable GetOverridesForUser(GameUser user, GameDatabaseCon Debug.Assert(this.UserHasOverrides(user), "User does not have overrides, should be checked first"); List overrides = this._userIdsToLevelList[user.UserId]; - this.Logger.LogDebug(RefreshContext.LevelListOverride, "Getting level override for {0}: [{1}]", user, string.Join(", ", overrides)); + this.Logger.LogDebug(RefreshContext.LevelListOverride, "Getting level override for {0}: [{1}]", user.Username, string.Join(", ", overrides)); this._userIdsToLevelList.Remove(user.UserId); return overrides.Select(database.GetLevelById)!; From 3701a9e850b0f55c6485c17b5d96c22307c74ca1 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 14:56:51 -0400 Subject: [PATCH 5/9] fix wtf formatting --- Refresh.GameServer/Services/CommandService.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Refresh.GameServer/Services/CommandService.cs b/Refresh.GameServer/Services/CommandService.cs index fd0c0e6a..824f8837 100644 --- a/Refresh.GameServer/Services/CommandService.cs +++ b/Refresh.GameServer/Services/CommandService.cs @@ -80,7 +80,8 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas { switch (command.Name) { - case "forcematch": { + case "forcematch": + { if (command.Arguments == null) { throw new Exception("User not provided for force match command"); @@ -95,19 +96,19 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas break; } - case "clearforcematch": { + case "clearforcematch": + { this._match.ClearForceMatch(user.UserId); - break; } - case "griefphotoson": { + case "griefphotoson": + { user.RedirectGriefReportsToPhotos = true; - break; } - case "griefphotosoff": { + case "griefphotosoff": + { user.RedirectGriefReportsToPhotos = false; - break; } #if DEBUG From 69b858903a551e00f44de73ba4de5be9a3875a6a Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 15:28:31 -0400 Subject: [PATCH 6/9] Add in-game command for setting a level override --- .../Endpoints/Game/ModerationEndpoints.cs | 5 +++-- Refresh.GameServer/Services/CommandService.cs | 12 +++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs b/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs index ec0ccfe5..e560e548 100644 --- a/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs +++ b/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs @@ -43,7 +43,7 @@ public SerializedModeratedResourceList ModerateResources(RequestContext context, /// The string shown in-game. [GameEndpoint("filter", HttpMethods.Post)] [AllowEmptyBody] - public string Filter(RequestContext context, CommandService commandService, string body, GameUser user, Token token, GameDatabaseContext database) + public string Filter(RequestContext context, CommandService commandService, string body, GameUser user, Token token, GameDatabaseContext database, LevelListOverrideService levelListService) { // TODO: Add actual filtering/censoring @@ -61,7 +61,8 @@ public string Filter(RequestContext context, CommandService commandService, stri context.Logger.LogInfo(BunkumCategory.Commands, $"User used command '{command.Name.ToString()}' with args '{command.Arguments.ToString()}'"); - commandService.HandleCommand(command, database, user, token); + commandService.HandleCommand(command, database, levelListService, user, token); + return "(Command)"; } catch { diff --git a/Refresh.GameServer/Services/CommandService.cs b/Refresh.GameServer/Services/CommandService.cs index 824f8837..33fb9223 100644 --- a/Refresh.GameServer/Services/CommandService.cs +++ b/Refresh.GameServer/Services/CommandService.cs @@ -6,6 +6,7 @@ using Refresh.GameServer.Authentication; using Refresh.GameServer.Database; using Refresh.GameServer.Types.Commands; +using Refresh.GameServer.Types.Levels; using Refresh.GameServer.Types.UserData; namespace Refresh.GameServer.Services; @@ -76,7 +77,7 @@ public CommandInvocation ParseCommand(ReadOnlySpan input) } [SuppressMessage("ReSharper", "StringLiteralTypo")] - public void HandleCommand(CommandInvocation command, GameDatabaseContext database, GameUser user, Token token) + public void HandleCommand(CommandInvocation command, GameDatabaseContext database, LevelListOverrideService levelListService, GameUser user, Token token) { switch (command.Name) { @@ -111,6 +112,15 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas user.RedirectGriefReportsToPhotos = false; break; } + case "play": + { + GameLevel? level = database.GetLevelById(int.Parse(command.Arguments)); + if (level != null) + { + levelListService.AddOverridesForUser(user, level); + } + break; + } #if DEBUG case "tokengame": { From 182e2eb065962b37a3189fc3fdc7651d2506d506 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 15:38:54 -0400 Subject: [PATCH 7/9] Don't require passing in LevelListOverrideService into cvommand invocation --- Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs | 4 ++-- Refresh.GameServer/Services/CommandService.cs | 8 +++++--- .../Tests/Commands/CommandParseTests.cs | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs b/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs index e560e548..f655de62 100644 --- a/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs +++ b/Refresh.GameServer/Endpoints/Game/ModerationEndpoints.cs @@ -43,7 +43,7 @@ public SerializedModeratedResourceList ModerateResources(RequestContext context, /// The string shown in-game. [GameEndpoint("filter", HttpMethods.Post)] [AllowEmptyBody] - public string Filter(RequestContext context, CommandService commandService, string body, GameUser user, Token token, GameDatabaseContext database, LevelListOverrideService levelListService) + public string Filter(RequestContext context, CommandService commandService, string body, GameUser user, Token token, GameDatabaseContext database) { // TODO: Add actual filtering/censoring @@ -61,7 +61,7 @@ public string Filter(RequestContext context, CommandService commandService, stri context.Logger.LogInfo(BunkumCategory.Commands, $"User used command '{command.Name.ToString()}' with args '{command.Arguments.ToString()}'"); - commandService.HandleCommand(command, database, levelListService, user, token); + commandService.HandleCommand(command, database, user, token); return "(Command)"; } catch diff --git a/Refresh.GameServer/Services/CommandService.cs b/Refresh.GameServer/Services/CommandService.cs index 33fb9223..f443ce9b 100644 --- a/Refresh.GameServer/Services/CommandService.cs +++ b/Refresh.GameServer/Services/CommandService.cs @@ -14,9 +14,11 @@ namespace Refresh.GameServer.Services; public class CommandService : EndpointService { private readonly MatchService _match; + private readonly LevelListOverrideService _levelListService; - public CommandService(Logger logger, MatchService match) : base(logger) { + public CommandService(Logger logger, MatchService match, LevelListOverrideService levelListService) : base(logger) { this._match = match; + this._levelListService = levelListService; } private readonly HashSet _usersPublishing = new(); @@ -77,7 +79,7 @@ public CommandInvocation ParseCommand(ReadOnlySpan input) } [SuppressMessage("ReSharper", "StringLiteralTypo")] - public void HandleCommand(CommandInvocation command, GameDatabaseContext database, LevelListOverrideService levelListService, GameUser user, Token token) + public void HandleCommand(CommandInvocation command, GameDatabaseContext database, GameUser user, Token token) { switch (command.Name) { @@ -117,7 +119,7 @@ public void HandleCommand(CommandInvocation command, GameDatabaseContext databas GameLevel? level = database.GetLevelById(int.Parse(command.Arguments)); if (level != null) { - levelListService.AddOverridesForUser(user, level); + this._levelListService.AddOverridesForUser(user, level); } break; } diff --git a/RefreshTests.GameServer/Tests/Commands/CommandParseTests.cs b/RefreshTests.GameServer/Tests/Commands/CommandParseTests.cs index f06005d1..555da5de 100644 --- a/RefreshTests.GameServer/Tests/Commands/CommandParseTests.cs +++ b/RefreshTests.GameServer/Tests/Commands/CommandParseTests.cs @@ -20,7 +20,7 @@ private void ParseTest(CommandService service, ReadOnlySpan input, ReadOnl public void ParsingTest() { using Logger logger = new(new []{ new NUnitSink() }); - CommandService service = new(logger, new MatchService(logger)); + CommandService service = new(logger, new MatchService(logger), new LevelListOverrideService(logger)); ParseTest(service, "/parse test", "parse", "test"); ParseTest(service, "/noargs", "noargs", ""); @@ -31,7 +31,7 @@ public void ParsingTest() public void NoSlashThrows() { using Logger logger = new(new []{ new NUnitSink() }); - CommandService service = new(logger, new MatchService(logger)); + CommandService service = new(logger, new MatchService(logger), new LevelListOverrideService(logger)); Assert.That(() => _ = service.ParseCommand("parse test"), Throws.InstanceOf()); } @@ -40,7 +40,7 @@ public void NoSlashThrows() public void BlankCommandThrows() { using Logger logger = new(new []{ new NUnitSink() }); - CommandService service = new(logger, new MatchService(logger)); + CommandService service = new(logger, new MatchService(logger), new LevelListOverrideService(logger)); Assert.That(() => _ = service.ParseCommand("/ test"), Throws.InstanceOf()); } From 6fe50c78de6b036a39355ce4101c8ae386aa9014 Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 15:40:26 -0400 Subject: [PATCH 8/9] dont FUCK up --- RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs index d51b62be..9cc57d4e 100644 --- a/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs +++ b/RefreshTests.GameServer/GameServer/TestRefreshGameServer.cs @@ -68,9 +68,9 @@ protected override void SetupServices() this._server.AddService(this.DateTimeProvider); this._server.AddService(); this._server.AddService(); - this._server.AddService(); this._server.AddService(); this._server.AddService(); + this._server.AddService(); } [Pure] From f515882eefbfa465879033bcc2e49ed5474b0a4f Mon Sep 17 00:00:00 2001 From: jvyden Date: Fri, 3 Nov 2023 15:42:14 -0400 Subject: [PATCH 9/9] FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUCCCCCCCCCCCCKKKKKKKKKK --- Refresh.GameServer/RefreshGameServer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Refresh.GameServer/RefreshGameServer.cs b/Refresh.GameServer/RefreshGameServer.cs index 848d5634..929fcfcd 100644 --- a/Refresh.GameServer/RefreshGameServer.cs +++ b/Refresh.GameServer/RefreshGameServer.cs @@ -125,7 +125,6 @@ protected virtual void SetupServices() this._server.AddService(); this._server.AddService(); this._server.AddService(); - this._server.AddService(); this._server.AddService(); this._server.AddService(); this._server.AddAutoDiscover(serverBrand: $"{this._config!.InstanceName} (Refresh)", @@ -147,6 +146,8 @@ protected virtual void SetupServices() this._server.AddService(); + this._server.AddService(); + #if DEBUG this._server.AddService(); #endif