diff --git a/OsuLazerServer/Attributes/AuthorizationAttribute.cs b/OsuLazerServer/Attributes/AuthorizationAttribute.cs index 8be3bb83eff2743da71da26ec07e04231d9d78ad..05f51d88952b8aa01d5f27f87d5e2e60cc0e6135 100644 --- a/OsuLazerServer/Attributes/AuthorizationAttribute.cs +++ b/OsuLazerServer/Attributes/AuthorizationAttribute.cs @@ -32,7 +32,7 @@ public class AuthorizationAttribute : ActionFilterAttribute DateTimeOffset.UtcNow.ToUnixTimeSeconds()) { context.HttpContext.Response.StatusCode = 401; - await context.HttpContext.Response.WriteAsJsonAsync(new {error = "User not logged in."}); + await context.HttpContext.Response.WriteAsJsonAsync(new {error = "Unauthorized"}); await context.HttpContext.Response.CompleteAsync(); } diff --git a/OsuLazerServer/Controllers/Beatmaps/BeatmapSetController.cs b/OsuLazerServer/Controllers/Beatmaps/BeatmapSetController.cs index 9ee797003d79cb5d0976a64d72b745271a93cad4..74ebdb978685a15c0d855c776e59d3176567f549 100644 --- a/OsuLazerServer/Controllers/Beatmaps/BeatmapSetController.cs +++ b/OsuLazerServer/Controllers/Beatmaps/BeatmapSetController.cs @@ -18,6 +18,8 @@ public class BeatmapSetController : Controller _resolver = resolver; _context = context; } + + [HttpGet] public async Task Index([FromRoute(Name = "setId")] int setId) { var beatmapset = await _resolver.FetchSetAsync(setId); diff --git a/OsuLazerServer/Controllers/Beatmaps/BeatmapsController.cs b/OsuLazerServer/Controllers/Beatmaps/BeatmapsController.cs index 9cd2aa3b5f2e520a2f37b9400415eab67a92f890..d29ce98d1b5e700551dd3b3d9a0f564283b69d17 100644 --- a/OsuLazerServer/Controllers/Beatmaps/BeatmapsController.cs +++ b/OsuLazerServer/Controllers/Beatmaps/BeatmapsController.cs @@ -200,7 +200,7 @@ public class BeatmapsController : Controller stats.RankedScore += score.TotalScore; stats.PerfomancePoints += (int) Math.Floor(score.PerfomancePoints??0); - } + } score.Status = DbScoreStatus.OUTDATED; @@ -218,10 +218,7 @@ public class BeatmapsController : Controller stats.Accuracy = (float)(_context.Scores.Where(s => s.Passed && s.UserId == user.Id).Select(a => a.Accuracy * 100) .ToList().Average() / 100F); } - } - - await _context.SaveChangesAsync(); diff --git a/OsuLazerServer/Controllers/Users/UsersController.cs b/OsuLazerServer/Controllers/Users/UsersController.cs index f695d7e08963bf9ea1134f43d7d3eff0a442a6fb..fa5f2184e3b9048b8b9691db9f0e48828295fc37 100644 --- a/OsuLazerServer/Controllers/Users/UsersController.cs +++ b/OsuLazerServer/Controllers/Users/UsersController.cs @@ -1,15 +1,19 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using Microsoft.AspNetCore.Mvc; +using Nager.Country; using OsuLazerServer.Attributes; using OsuLazerServer.Database; using OsuLazerServer.Database.Tables; using OsuLazerServer.Database.Tables.Scores; using OsuLazerServer.Models; using OsuLazerServer.Models.Response.Users; +using OsuLazerServer.Models.Spectator; using OsuLazerServer.Services.Beatmaps; using OsuLazerServer.Services.Users; using OsuLazerServer.Utils; +using Realms; +using Country = OsuLazerServer.Models.Country; namespace OsuLazerServer.Controllers; @@ -124,4 +128,57 @@ public class UsersController : Controller } + + + [HttpGet("/api/v2/users/")] + public async Task GetUrl() + { + var uri = Request.QueryString.Value; + + var ids = uri.Split("?").Last().Split("&").Select(s => s.Replace("ids[]=", "")).Select(val => Convert.ToInt32(val)); + + + return Json(new {users = ids.Select(id => toSpectatorUser(id))}); + } + + private SpectatorUser toSpectatorUser(int id) + { + var user = _context.Users.FirstOrDefault(d => d.Id == id); + + return new SpectatorUser + { + Country = new Country + { + Code = user.Country, + Name = new CountryProvider().GetCountry(user.Country).CommonName + }, + CountryCode = user.Country, + Cover = new Cover + { + Id = null, + CustomUrl = "https://media.discordapp.net/attachments/805142641427218452/954414155539046430/FOG8Lr3VQAAgi7t.jpg", + Url = "https://media.discordapp.net/attachments/805142641427218452/954414155539046430/FOG8Lr3VQAAgi7t.jpg" + }, + DefaultGroup = "default", + Groups = new List(), + Id = user.Id, + IsActive = true, + IsBot = false, + IsDeleted = false, + IsOnline = _storage.Users.Values.Any(d => d.Id == id), + IsSupporter = true, + LastVisit = DateTime.Now, + PmFriendsOnly = false, + ProfileColour = null, + StatisticsRuleset = new Dictionary + { + {"fruits", ModeUtils.FetchUserStats(new LazerContext(), "fruits", user.Id).ToOsu("fruits")}, + {"mania", ModeUtils.FetchUserStats(new LazerContext(), "mania", user.Id).ToOsu("mania")}, + {"osu", ModeUtils.FetchUserStats(new LazerContext(), "osu", user.Id).ToOsu("osu")}, + {"taiko", ModeUtils.FetchUserStats(new LazerContext(), "taiko", user.Id).ToOsu("taiko")}, + }, + Username = user.Username + + }; + } } \ No newline at end of file diff --git a/OsuLazerServer/Database/Tables/IUserStats.cs b/OsuLazerServer/Database/Tables/IUserStats.cs index 4c86afa02c12d75e5e402dd195d72734c4bda966..ebe8fc03ab3f745ffeaf2c2af3deaec46fccab25 100644 --- a/OsuLazerServer/Database/Tables/IUserStats.cs +++ b/OsuLazerServer/Database/Tables/IUserStats.cs @@ -1,5 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using OsuLazerServer.Models; +using OsuLazerServer.Utils; namespace OsuLazerServer.Database.Tables; @@ -19,4 +21,37 @@ public interface IUserStats [Column("maximum_combo")] public int MaxCombo { get; set; } [Column("ranked_score")] public long RankedScore { get; set; } [Column("accuracy")] public float Accuracy { get; set; } + + public Statistics ToOsu(string mode) => new Statistics + { + Level = new Level + { + Current = 0, + Progress = 0 + }, + CountryRank = 0, + GlobalRank = ModeUtils.GetRank(mode, Id), + HitAccuracy = Accuracy * 100, + IsRanked = true, + MaximumCombo = MaxCombo, + PlayCount = 0, + PlayTime = 0, + GradeCounts = new GradeCounts + { + A = 0, + S = 0, + Sh = 0, + Ss = 0, + Ssh = 0 + }, + PP = PerfomancePoints, + RankedScore = RankedScore, + TotalHits = (int) TotalHits, + TotalScore = TotalScore, + ReplaysWatchedByOthers = 0, + Rank = new Rank + { + Country = 0 + } + }; } \ No newline at end of file diff --git a/OsuLazerServer/Database/Tables/Scores/Score.cs b/OsuLazerServer/Database/Tables/Scores/Score.cs index 3c0e56d3c20eb5b5cc72a3524e9bb4b3061e2a5b..fff690dc2e0fecbbf088721aaa30451ecde1e67c 100644 --- a/OsuLazerServer/Database/Tables/Scores/Score.cs +++ b/OsuLazerServer/Database/Tables/Scores/Score.cs @@ -86,5 +86,6 @@ public class DbScore public enum DbScoreStatus { BEST, - OUTDATED + OUTDATED, + FIRST } \ No newline at end of file diff --git a/OsuLazerServer/Models/Spectator/SpectatorUser.cs b/OsuLazerServer/Models/Spectator/SpectatorUser.cs new file mode 100644 index 0000000000000000000000000000000000000000..4c3f0e65a7bd3bf5321aedecb737f53150e131ef --- /dev/null +++ b/OsuLazerServer/Models/Spectator/SpectatorUser.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; +using OsuLazerServer.Database.Tables; +using Realms; + +namespace OsuLazerServer.Models.Spectator; + +public class SpectatorUser : APIUser +{ + + [JsonPropertyName("statistics_rulesets")] + public Dictionary StatisticsRuleset { get; set; } +} \ No newline at end of file diff --git a/OsuLazerServer/Services/Beatmaps/BeatmapTypes.cs b/OsuLazerServer/Services/Beatmaps/BeatmapTypes.cs index 68f344ca169ac9b004465d919fb2d9f4d376e10c..0a3102a6d92a7217bac09f104de627de7f08fcd4 100644 --- a/OsuLazerServer/Services/Beatmaps/BeatmapTypes.cs +++ b/OsuLazerServer/Services/Beatmaps/BeatmapTypes.cs @@ -285,13 +285,13 @@ namespace OsuLazerServer.Services.Beatmaps; }, Beatmaps = Beatmaps?.Select(beatmap => new APIBeatmap { - Checksum = beatmap.Checksum, - Length = beatmap.HitLength, - Status = BeatmapUtils.Status(beatmap.Status.ToLower()), - DifficultyName = beatmap.Version, - StarRating = beatmap.DifficultyRating, - OnlineID = beatmap.Id, - RulesetID = beatmap.ModeInt, + Checksum = beatmap?.Checksum??"", + Length = beatmap?.HitLength??0, + Status = BeatmapUtils.Status(beatmap?.Status?.ToLower()??"graveyard"), + DifficultyName = beatmap?.Version??"", + StarRating = beatmap?.DifficultyRating??0, + OnlineID = beatmap?.Id??0, + RulesetID = beatmap?.ModeInt??0, OnlineBeatmapSetID = Id }).ToArray()??new APIBeatmap[] {}, Covers = new BeatmapSetOnlineCovers diff --git a/OsuLazerServer/Services/Users/IUserStorage.cs b/OsuLazerServer/Services/Users/IUserStorage.cs index ccdd5514a0a7ee39c61341c77d64daeae5658a97..5fde5eb1eae1eaf8d27231943744d0b3c3d7bec6 100644 --- a/OsuLazerServer/Services/Users/IUserStorage.cs +++ b/OsuLazerServer/Services/Users/IUserStorage.cs @@ -32,6 +32,6 @@ public interface IUserStorage public Task GetUpdatesForUser(int userId); public Task GetChannelAsync(int channelId, LazerContext context, bool forceFetch = false); - + public Task ForceJoinChannel(int id, int channelId); } diff --git a/OsuLazerServer/Services/Users/UserStorage.cs b/OsuLazerServer/Services/Users/UserStorage.cs index b938ca9cb750c2be147926cd7c52d355c987f68f..78f398e89aec7ca6374a9707074a9f293bc620dc 100644 --- a/OsuLazerServer/Services/Users/UserStorage.cs +++ b/OsuLazerServer/Services/Users/UserStorage.cs @@ -125,6 +125,22 @@ public class UserStorage : IUserStorage, IServiceScope return newChannel; } + public Task ForceJOinChannel(int id, int channelId) + { + throw new NotImplementedException(); + } + + public async Task ForceJoinChannel(int userId, int channelId) + { + var channel = await GetChannelAsync(channelId, new LazerContext()); + + await AddUpdate(userId, new Update + { + Channels = new List { channel }, + Messages = new List() + }); + } + public async Task NotifyUser(int userId, string message) { await AddUpdate(userId, new Update diff --git a/OsuLazerServer/Services/Wiki/WikiResolverService.cs b/OsuLazerServer/Services/Wiki/WikiResolverService.cs index efbf32b82af4f70547adaa3a9de6d403398b9f60..7c159c9aafa4ba4e5c024a0f64af64a01dd55494 100644 --- a/OsuLazerServer/Services/Wiki/WikiResolverService.cs +++ b/OsuLazerServer/Services/Wiki/WikiResolverService.cs @@ -41,9 +41,9 @@ public class WikiResolverService : IWikiResolver public WikiInfo GetWikiPage(string wiki) { - var wikiInfo = JsonSerializer.Deserialize(File.ReadAllText(Path.Combine("Data", "wiki", wiki, "info.json"))); + var wikiInfo = JsonSerializer.Deserialize(File.ReadAllText(Path.Combine("Data", "wiki", Path.GetFileName(wiki), "info.json"))); - var markdown = File.ReadAllText(Path.Combine("data", "wiki", wiki, "page.md")); + var markdown = File.ReadAllText(Path.Combine("data", "wiki", Path.GetFileName(wiki), "page.md")); wikiInfo.Content = markdown;