diff options
m--------- | LibMatrix | 0 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi.sln.DotSettings.user | 2 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/Controllers/BeatmapRepositoryController.cs | 7 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/Events/State/BeatmapSetInfo.cs | 36 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/OsuFederatedBeatmapApi.csproj | 1 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/Program.cs | 3 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/Services/BeatmapFetcherService.cs | 34 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/Services/FederatedBeatmapApiBot.cs | 23 | ||||
-rw-r--r-- | OsuFederatedBeatmapApi/UtilityClasses/OsuDirectApiResponses.cs | 107 |
9 files changed, 207 insertions, 6 deletions
diff --git a/LibMatrix b/LibMatrix -Subproject 84e33226690beb65f747526714ac9aa4cc8ee15 +Subproject 4340b1899470c06f170817dbc1200040619fbf8 diff --git a/OsuFederatedBeatmapApi.sln.DotSettings.user b/OsuFederatedBeatmapApi.sln.DotSettings.user index d5ce503..98ceabe 100644 --- a/OsuFederatedBeatmapApi.sln.DotSettings.user +++ b/OsuFederatedBeatmapApi.sln.DotSettings.user @@ -1,3 +1,3 @@ <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> - <s:Int64 x:Key="/Default/Dpa/Thresholds/=AllocationClosure/@EntryIndexedValue">52428800</s:Int64> + <s:Int64 x:Key="/Default/Dpa/Thresholds/=AllocationClosure/@EntryIndexedValue">53477376</s:Int64> <s:Int64 x:Key="/Default/Dpa/Thresholds/=AllocationLoh/@EntryIndexedValue">52428800</s:Int64></wpf:ResourceDictionary> \ No newline at end of file diff --git a/OsuFederatedBeatmapApi/Controllers/BeatmapRepositoryController.cs b/OsuFederatedBeatmapApi/Controllers/BeatmapRepositoryController.cs index 6a1149d..b1fa4f1 100644 --- a/OsuFederatedBeatmapApi/Controllers/BeatmapRepositoryController.cs +++ b/OsuFederatedBeatmapApi/Controllers/BeatmapRepositoryController.cs @@ -6,7 +6,7 @@ namespace OsuFederatedBeatmapApi.Controllers; [ApiController] [Route("/")] -public class BeatmapRepositoryController(ILogger<BeatmapRepositoryController> logger, FederatedBeatmapApiBotAccountDataService ads) : ControllerBase { +public class BeatmapRepositoryController(ILogger<BeatmapRepositoryController> logger, FederatedBeatmapApiBotAccountDataService ads, BeatmapFetcherService bfs) : ControllerBase { [HttpGet("/beatmapset/all/info")] public async IAsyncEnumerable<BeatmapSetInfo> GetAllInfo() { await ads.LoadAccountDataAsync(); @@ -24,8 +24,9 @@ public class BeatmapRepositoryController(ILogger<BeatmapRepositoryController> lo await ads.LoadAccountDataAsync(); foreach (var repo in ads.ListedRepositories) { - var states = await repo.GetStateAsync<BeatmapSetInfo>("gay.rory.beatmap_api.beatmap_set_info", id.ToString()); - return states as BeatmapSetInfo; + var state = await repo.GetStateOrNullAsync<BeatmapSetInfo>("gay.rory.beatmap_api.beatmap_set_info", id.ToString()); + if (state is not null) return state; + return await bfs.FetchBeatmapSetInfo(id); } return null; diff --git a/OsuFederatedBeatmapApi/Events/State/BeatmapSetInfo.cs b/OsuFederatedBeatmapApi/Events/State/BeatmapSetInfo.cs index 8cfcf0d..7d6b455 100644 --- a/OsuFederatedBeatmapApi/Events/State/BeatmapSetInfo.cs +++ b/OsuFederatedBeatmapApi/Events/State/BeatmapSetInfo.cs @@ -1,12 +1,46 @@ +using System.Text.Json.Serialization; using LibMatrix; using LibMatrix.EventTypes; using LibMatrix.Interfaces; namespace OsuFederatedBeatmapApi.Events.State; -[MatrixEvent(EventName = "gay.rory.beatmap_api.beatmap_set_info")] +[MatrixEvent(EventName = EventName)] public class BeatmapSetInfo : EventContent { + public const string EventName = "gay.rory.beatmap_api.beatmap_set_info"; + [JsonPropertyName("title")] + public string? Title { get; set; } + [JsonPropertyName("artist")] + public string? Artist { get; set; } + [JsonPropertyName("creator")] + public string? Creator { get; set; } + + [JsonPropertyName("beatmaps")] + public Dictionary<int, BeatmapInfo> Beatmaps { get; set; } = new(); + + public class BeatmapInfo { + [JsonPropertyName("difficulty")] + public string? Difficulty { get; set; } + + [JsonPropertyName("mode")] + public int? Mode { get; set; } + + [JsonPropertyName("difficulty_rating")] + public double? DifficultyRating { get; set; } + + [JsonPropertyName("total_length")] + public int? TotalLength { get; set; } + + [JsonPropertyName("bpm")] + public double? BPM { get; set; } + + [JsonPropertyName("max_combo")] + public int? MaxCombo { get; set; } + + // [JsonPropertyName("drain")] + // public double? Drain { get; set; } + } } diff --git a/OsuFederatedBeatmapApi/OsuFederatedBeatmapApi.csproj b/OsuFederatedBeatmapApi/OsuFederatedBeatmapApi.csproj index 387808f..bc2a324 100644 --- a/OsuFederatedBeatmapApi/OsuFederatedBeatmapApi.csproj +++ b/OsuFederatedBeatmapApi/OsuFederatedBeatmapApi.csproj @@ -14,6 +14,7 @@ <ItemGroup> <ProjectReference Include="..\LibMatrix\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj" /> + </ItemGroup> diff --git a/OsuFederatedBeatmapApi/Program.cs b/OsuFederatedBeatmapApi/Program.cs index 15f9b12..8f54865 100644 --- a/OsuFederatedBeatmapApi/Program.cs +++ b/OsuFederatedBeatmapApi/Program.cs @@ -1,3 +1,4 @@ +using System.Text.Json; using LibMatrix.Services; using LibMatrix.Utilities.Bot; using OsuFederatedBeatmapApi.Services; @@ -21,6 +22,8 @@ builder.Services.AddScoped<TieredStorageService>(x => builder.Services.AddRoryLibMatrixServices(); builder.Services.AddBot(withCommands: true); +builder.Services.AddScoped<BeatmapFetcherService>(); + builder.Services.AddSingleton<FederatedBeatmapApiBotConfiguration>(); builder.Services.AddScoped<FederatedBeatmapApiBotAccountDataService>(); builder.Services.AddHostedService<FederatedBeatmapApiBot>(); diff --git a/OsuFederatedBeatmapApi/Services/BeatmapFetcherService.cs b/OsuFederatedBeatmapApi/Services/BeatmapFetcherService.cs new file mode 100644 index 0000000..ae108fb --- /dev/null +++ b/OsuFederatedBeatmapApi/Services/BeatmapFetcherService.cs @@ -0,0 +1,34 @@ +using System.Net.Http.Headers; +using OsuFederatedBeatmapApi.Events.State; +using OsuFederatedBeatmapApi.UtilityClasses; + +namespace OsuFederatedBeatmapApi.Services; + +public class BeatmapFetcherService(FederatedBeatmapApiBotAccountDataService ads) { + + public async Task<BeatmapSetInfo> FetchBeatmapSetInfo(int id) { + var hc = new HttpClient(); + hc.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("OsuFederatedBeatmapApi", "1.0")); + var res = await hc.GetFromJsonAsync<OsuDirectApiResponses.BeatmapSet>($"https://osu.direct/api/s/{id}"); + var info = new BeatmapSetInfo { + Title = res.Title, + Artist = res.Artist, + Creator = res.Creator, + Beatmaps = res.ChildrenBeatmaps.ToDictionary(b => b.BeatmapID, b => new BeatmapSetInfo.BeatmapInfo { + Difficulty = b.DiffName, + Mode = b.Mode, + DifficultyRating = b.DifficultyRating, + TotalLength = b.TotalLength, + BPM = b.BPM, + MaxCombo = b.MaxCombo + }) + }; + + await ads.LoadAccountDataAsync(); + + await ads.OwnBeatmapRepositoryRoom.SendStateEventAsync(BeatmapSetInfo.EventName, id.ToString(), info); + + return info; + } + +} diff --git a/OsuFederatedBeatmapApi/Services/FederatedBeatmapApiBot.cs b/OsuFederatedBeatmapApi/Services/FederatedBeatmapApiBot.cs index b8cc635..2aaf45c 100644 --- a/OsuFederatedBeatmapApi/Services/FederatedBeatmapApiBot.cs +++ b/OsuFederatedBeatmapApi/Services/FederatedBeatmapApiBot.cs @@ -40,7 +40,28 @@ public class FederatedBeatmapApiBot(AuthenticatedHomeserverGeneric hs, var controlRoomMembers = accountDataService.ControlRoom.GetMembersAsync(); await foreach (var member in controlRoomMembers) { if ((member.TypedContent as RoomMemberEventContent)? - .Membership == "join") admins.Add(member.UserId); + .Membership == "join") + admins.Add(member.StateKey); + } + + var pls = await accountDataService.OwnBeatmapRepositoryRoom.GetPowerLevelsAsync(); + var ownPl = pls.GetUserPowerLevel(hs.UserId); + + if (!pls.UserHasPermission(hs.UserId, RoomPowerLevelEventContent.EventId)) { + accountDataService.LogRoom.SendMessageEventAsync( + MessageFormatter.FormatError( + $"I don't have permission to send power level updates in " + + $"{MessageFormatter.HtmlFormatMention(accountDataService.OwnBeatmapRepositoryRoom.RoomId, "my own beatmap repository")}!")); + } + else { + foreach (var admin in admins) { + if (pls.GetUserPowerLevel(admin) < ownPl - 1) { + logger.LogInformation("Raising powerlevel of {} in {} to {}", admin, accountDataService.OwnBeatmapRepositoryRoom.RoomId, ownPl - 1); + pls.SetUserPowerLevel(admin, ownPl - 1); + await accountDataService.OwnBeatmapRepositoryRoom.SendStateEventAsync( + RoomPowerLevelEventContent.EventId, pls); + } + } } await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken); diff --git a/OsuFederatedBeatmapApi/UtilityClasses/OsuDirectApiResponses.cs b/OsuFederatedBeatmapApi/UtilityClasses/OsuDirectApiResponses.cs new file mode 100644 index 0000000..b7b67b1 --- /dev/null +++ b/OsuFederatedBeatmapApi/UtilityClasses/OsuDirectApiResponses.cs @@ -0,0 +1,107 @@ +using System.Text.Json.Serialization; + +namespace OsuFederatedBeatmapApi.UtilityClasses; + +public class OsuDirectApiResponses { + public class ChildrenBeatmap + { + [JsonPropertyName("ParentSetID")] + public int ParentSetID { get; set; } + + [JsonPropertyName("BeatmapID")] + public int BeatmapID { get; set; } + + [JsonPropertyName("TotalLength")] + public int TotalLength { get; set; } + + [JsonPropertyName("HitLength")] + public int HitLength { get; set; } + + [JsonPropertyName("DiffName")] + public string DiffName { get; set; } + + [JsonPropertyName("FileMD5")] + public string FileMD5 { get; set; } + + [JsonPropertyName("CS")] + public int CS { get; set; } + + [JsonPropertyName("AR")] + public int AR { get; set; } + + [JsonPropertyName("HP")] + public int HP { get; set; } + + [JsonPropertyName("OD")] + public int OD { get; set; } + + [JsonPropertyName("Mode")] + public int Mode { get; set; } + + [JsonPropertyName("BPM")] + public int BPM { get; set; } + + [JsonPropertyName("Playcount")] + public int Playcount { get; set; } + + [JsonPropertyName("Passcount")] + public int Passcount { get; set; } + + [JsonPropertyName("MaxCombo")] + public int MaxCombo { get; set; } + + [JsonPropertyName("DifficultyRating")] + public double DifficultyRating { get; set; } + } + + public class BeatmapSet + { + [JsonPropertyName("SetID")] + public int SetID { get; set; } + + [JsonPropertyName("Title")] + public string Title { get; set; } + + [JsonPropertyName("Artist")] + public string Artist { get; set; } + + [JsonPropertyName("Creator")] + public string Creator { get; set; } + + [JsonPropertyName("Source")] + public string Source { get; set; } + + [JsonPropertyName("Tags")] + public string Tags { get; set; } + + [JsonPropertyName("RankedStatus")] + public int RankedStatus { get; set; } + + [JsonPropertyName("Genre")] + public int Genre { get; set; } + + [JsonPropertyName("Language")] + public int Language { get; set; } + + [JsonPropertyName("Favourites")] + public int Favourites { get; set; } + + [JsonPropertyName("HasVideo")] + public int HasVideo { get; set; } + + [JsonPropertyName("SubmittedDate")] + public DateTime SubmittedDate { get; set; } + + [JsonPropertyName("ApprovedDate")] + public DateTime ApprovedDate { get; set; } + + [JsonPropertyName("LastUpdate")] + public DateTime LastUpdate { get; set; } + + [JsonPropertyName("LastChecked")] + public DateTime LastChecked { get; set; } + + [JsonPropertyName("ChildrenBeatmaps")] + public List<ChildrenBeatmap> ChildrenBeatmaps { get; set; } + } +} |