From 3a4678c3e0b0a89277d8e66c456c943ed0f782f5 Mon Sep 17 00:00:00 2001 From: KedamaOvO Date: Tue, 9 Apr 2019 12:03:34 +0800 Subject: [PATCH] add ExtraApi /api/extra/fcpp/{acc} --- OsuDataDistributeRestful.csproj | 1 + OsuDataDistributeRestfulPlugin.cs | 35 ++++++---- Server/ActionResult.cs | 19 ++++- Server/Api/ExtraApis.cs | 111 ++++++++++++++++++++++++++++++ Server/Api/OlspApis.cs | 10 +-- Server/Api/OrtdpApis.cs | 8 +-- Server/Api/RtppdApis.cs | 9 +-- Server/ApiServer.cs | 45 ++++++++---- Server/ServerBase.cs | 13 +++- 9 files changed, 209 insertions(+), 42 deletions(-) create mode 100644 Server/Api/ExtraApis.cs diff --git a/OsuDataDistributeRestful.csproj b/OsuDataDistributeRestful.csproj index 27f4b51..89ae5c3 100644 --- a/OsuDataDistributeRestful.csproj +++ b/OsuDataDistributeRestful.csproj @@ -59,6 +59,7 @@ + diff --git a/OsuDataDistributeRestfulPlugin.cs b/OsuDataDistributeRestfulPlugin.cs index f7ced99..ee830b5 100644 --- a/OsuDataDistributeRestfulPlugin.cs +++ b/OsuDataDistributeRestfulPlugin.cs @@ -54,46 +54,57 @@ private void PrintLanAddress() #region Initializtion - private void ORTDP_Initialize() + private Plugin ORTDP_Initialize() { var plugin = getHoster().EnumPluings().Where(p => p.Name == "OsuRTDataProvider").FirstOrDefault(); if (plugin != null) { ApiServer.RegisterResource(new OrtdpApis(plugin)); + return plugin; } - else - IO.CurrentIO.WriteColor($"[ODDR]Not Found OsuRTDataProvider", ConsoleColor.Red); + + IO.CurrentIO.WriteColor($"[ODDR]Not Found OsuRTDataProvider", ConsoleColor.Red); + return null; } - private void RTPPD_Initialize() + private Plugin RTPPD_Initialize() { var plugin = getHoster().EnumPluings().Where(p => p.Name == "RealTimePPDisplayer").FirstOrDefault(); if (plugin != null) { ApiServer.RegisterResource(new RtppdApis(plugin)); + return plugin; } - else - IO.CurrentIO.WriteColor($"[ODDR]Not Found RealTimePPDisplayer", ConsoleColor.Red); + + IO.CurrentIO.WriteColor($"[ODDR]Not Found RealTimePPDisplayer", ConsoleColor.Red); + return null; } - private void OLSP_Initialize() + private Plugin OLSP_Initialize() { var plugin = getHoster().EnumPluings().Where(p => p.Name == "OsuLiveStatusPanelPlugin").FirstOrDefault(); if (plugin != null) { ApiServer.RegisterResource(new OlspApis(plugin)); + return plugin; } - else - IO.CurrentIO.WriteColor($"[ODDR]Not Found OsuLiveStatusPanel", ConsoleColor.Red); + + IO.CurrentIO.WriteColor($"[ODDR]Not Found OsuLiveStatusPanel", ConsoleColor.Red); + return null; } #endregion Initializtion private void Initialize() { - ORTDP_Initialize(); - RTPPD_Initialize(); - OLSP_Initialize(); + var ortdp = ORTDP_Initialize(); + var rtppd = RTPPD_Initialize(); + var olsp = OLSP_Initialize(); + + if(ortdp !=null && rtppd != null) + { + ApiServer.RegisterResource(new ExtraApis(ortdp,rtppd)); + } } public override void OnEnable() diff --git a/Server/ActionResult.cs b/Server/ActionResult.cs index a3e6ced..9ad35d5 100644 --- a/Server/ActionResult.cs +++ b/Server/ActionResult.cs @@ -1,8 +1,9 @@ -using System.IO; +using Newtonsoft.Json; +using System.IO; namespace OsuDataDistributeRestful.Server { - internal class ActionResult + public class ActionResult { /// /// MIME @@ -11,13 +12,25 @@ internal class ActionResult public int Code { get; private set; } = 200; + public string Reason { get; private set; } = string.Empty; + public object Data { get; private set; } - public ActionResult(object a, int code = 200) + public Formatting Formatting { get; set; } = Formatting.None; + + public ActionResult(object a) + { + ContentType = "text/json; charset=UTF-8"; + Data = a; + Code = 200; + } + + public ActionResult(object a, int code, string reason) { ContentType = "text/json; charset=UTF-8"; Data = a; Code = code; + Reason = reason; } public ActionResult(Stream s, int code = 200) diff --git a/Server/Api/ExtraApis.cs b/Server/Api/ExtraApis.cs new file mode 100644 index 0000000..32155df --- /dev/null +++ b/Server/Api/ExtraApis.cs @@ -0,0 +1,111 @@ +using OsuDataDistributeRestful.Server.Api; +using OsuRTDataProvider; +using OsuRTDataProvider.BeatmapInfo; +using OsuRTDataProvider.Listen; +using OsuRTDataProvider.Mods; +using RealTimePPDisplayer; +using RealTimePPDisplayer.Beatmap; +using RealTimePPDisplayer.Calculator; +using Sync.Plugins; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OsuDataDistributeRestful.Server +{ + [Route("/api/extra")] + class ExtraApis:IApi + { + private OsuRTDataProviderPlugin _ortdp; + private RealTimePPDisplayerPlugin _rtppd; + private OsuPlayMode _mode; + private uint _mods; + + private PerformanceCalculatorBase _stdPpCalculator; + private PerformanceCalculatorBase _taikoPpCalculator; + private PerformanceCalculatorBase _maniaPpCalculator; + private PerformanceCalculatorBase _ctbPpCalculator; + + private Beatmap _beatmap; + private BeatmapReader _reader; + + public ExtraApis(Plugin ortdp,Plugin rtppd) + { + _ortdp = ortdp as OsuRTDataProviderPlugin; + _rtppd = rtppd as RealTimePPDisplayerPlugin; + + _ortdp.ListenerManager.OnPlayModeChanged += (l, c) => _mode = c; + _ortdp.ListenerManager.OnModsChanged += (c) => _mods = (uint)c.Mod; + _ortdp.ListenerManager.OnBeatmapChanged += (b) => _beatmap = b; + } + + [Route("/fcpp/{acc}")] + public object GetFcpp(double acc) + { + PerformanceCalculatorBase cal = GetCalculator(); + + if (cal is null) + { + return new ActionResult(null, 500, "The server could not get pp calculator."); + } + + if (_beatmap is null) + { + return new ActionResult(null, 500, "The server could not get beatmap."); + } + + if (_reader is null || + _reader.OrtdpBeatmap.BeatmapID != _beatmap.BeatmapID) + { + _reader = new BeatmapReader(_beatmap, (int)_mode); + } + + if(_reader is null) + { + return new ActionResult(null, 500, "The server could not create BeatmapReader."); + } + + cal.AccuracyRound(acc, _reader.ObjectsCount, 0, out int n300, out int n100, out int n50); + + cal.Mods = _mods; + cal.Beatmap = _reader; + cal.Count50 = n50; + cal.Count100 = n100; + cal.Count300 = n300; + cal.CountMiss = 0; + + var pptuple = cal.GetPerformance(); + + return new ActionResult(new + { + pp = pptuple.FullComboPP, + aim_pp = pptuple.FullComboAimPP, + speed_pp = pptuple.FullComboSpeedPP, + acc_pp = pptuple.FullComboAccuracyPP, + }); + } + + private PerformanceCalculatorBase GetCalculator() + { + switch (_mode) + { + case OsuPlayMode.Osu: + _stdPpCalculator = _stdPpCalculator ?? new StdPerformanceCalculator(); + return _stdPpCalculator; + case OsuPlayMode.Taiko: + _taikoPpCalculator = _taikoPpCalculator ?? new TaikoPerformanceCalculator(); + return _taikoPpCalculator; + case OsuPlayMode.Mania: + _maniaPpCalculator = _maniaPpCalculator ?? new ManiaPerformanceCalculator(); + return _maniaPpCalculator; + case OsuPlayMode.CatchTheBeat: + _ctbPpCalculator = _ctbPpCalculator ?? new CatchTheBeatPerformanceCalculator(); + return _ctbPpCalculator; + default: + return null; + } + } + } +} diff --git a/Server/Api/OlspApis.cs b/Server/Api/OlspApis.cs index 0e60703..0df3aab 100644 --- a/Server/Api/OlspApis.cs +++ b/Server/Api/OlspApis.cs @@ -21,7 +21,9 @@ public OlspApis(Plugin olsp_plguin) public ActionResult GetDictValue(string providable_data_name) { if (!olsp.EnumProvidableDataName().Any(p => p == providable_data_name)) - return new ActionResult(new { code = 404 }, 404); + { + return new ActionResult(null, 400, $"Invalid argument. Parameters:{string.Join(", ",olsp.EnumProvidableDataName())}"); + } var result = olsp.GetData(providable_data_name); return new ActionResult(new @@ -47,7 +49,7 @@ public ActionResult GetBackgoundImage() ContentType = GetContentType(ext) }; } - return new ActionResult(new { code = 404, message = "background image not found" }, 200); + return new ActionResult(null, 404, "No background image found"); } [Route("/image/output")] @@ -66,7 +68,7 @@ public ActionResult GetOuputBackgoundImage() ContentType = GetContentType(ext) }; } - return new ActionResult(new { code = 404, message = "output image not found" }, 200); + return new ActionResult(null, 404, "No output image found"); } [Route("/image/mods")] @@ -85,7 +87,7 @@ public ActionResult GetModsImage() ContentType = GetContentType(ext) }; } - return new ActionResult(new { code = 404, message = "mods image not found" }, 200); + return new ActionResult(null, 404, "No mods image found."); } private string GetContentType(string fileExtention) diff --git a/Server/Api/OrtdpApis.cs b/Server/Api/OrtdpApis.cs index 7af1fb7..edcf2a4 100644 --- a/Server/Api/OrtdpApis.cs +++ b/Server/Api/OrtdpApis.cs @@ -67,7 +67,7 @@ public object GetBeatmap() if (File.Exists(beatmap.FilenameFull)) return new ActionResult(File.OpenRead(beatmap.FilenameFull)) { ContentType = "text/plain; charset=utf-8" }; - return new ActionResult(new { code = 404, message = "no found beatmap file" }); + return new ActionResult(new { code = 404, message = "No beatmap found." }); } [Route("/beatmap/audio")] @@ -87,7 +87,7 @@ public ActionResult GetAudioFile() }; } - return new ActionResult(new { code = 404 }, 200); + return new ActionResult(null, 404,"No audio found."); } [Route("/beatmap/background")] @@ -108,7 +108,7 @@ public ActionResult GetBackgroundFile() }; } - return new ActionResult(new { code = 404 }, 200); + return new ActionResult(null, 404, "No backgournd image found."); } [Route("/beatmap/video")] @@ -129,7 +129,7 @@ public ActionResult GetVideoFile() }; } - return new ActionResult(new { code = 404 }, 200); + return new ActionResult(null, 404, "No video found."); } #endregion Beatmap diff --git a/Server/Api/RtppdApis.cs b/Server/Api/RtppdApis.cs index a62cdf1..d1cdad8 100644 --- a/Server/Api/RtppdApis.cs +++ b/Server/Api/RtppdApis.cs @@ -2,6 +2,7 @@ using OsuDataDistributeRestful.Server.Api; using RealTimePPDisplayer; using RealTimePPDisplayer.Displayer; +using RealTimePPDisplayer.Formatter; using Sync.Plugins; using System.Collections.Generic; using System.Linq; @@ -111,7 +112,7 @@ public object GetPPFormat() public object GetHitCountFormat() => new {format = StringFormatter.GetHitCountFormatter().Format }; - [Route("/formated/pp")] + [Route("/formatted/pp")] public object GetFormatedPP() { List displayers = EnumerateRestfulDisplayers(); @@ -123,21 +124,21 @@ public object GetFormatedPP() }; } - [Route("/formated/pp/{0}")] + [Route("/formatted/pp/{id}")] public object GetFormatedPP(int id) { RestfulDisplayer displayer = GetDisplayer(id); return displayer.FormatPp(); } - [Route("/formated/hitCount/{0}")] + [Route("/formatted/hitCount/{id}")] public object GetFormatedHitCount(int id) { RestfulDisplayer displayer = GetDisplayer(id); return displayer.FormatHitCount(); } - [Route("/formated/hitCount")] + [Route("/formatted/hitCount")] public object GetFormatedHitCount() { List displayers = EnumerateRestfulDisplayers(); diff --git a/Server/ApiServer.cs b/Server/ApiServer.cs index f86e698..436effa 100644 --- a/Server/ApiServer.cs +++ b/Server/ApiServer.cs @@ -19,7 +19,7 @@ public class ApiServer : ServerBase private struct Method { public MethodInfo MethodInfo; - public object Instance; + public IApi Instance; } private class ParamCollection : Dictionary @@ -111,7 +111,17 @@ public Apis(ApiServer apiServer) [Route("/api")] public object OutputAllApi() { - return m_apiServer.m_route_dict.Keys.Select(template => template.Template); + return new ActionResult(m_apiServer.m_route_dict + .GroupBy(p => p.Value.Instance) + .Select(g => new + { + name = g.Key.GetType().Name, + apis = g.Select(p => p.Key.Template) + }) + ) + { + Formatting = Formatting.Indented + }; } } @@ -164,22 +174,29 @@ protected override void OnResponse(HttpListenerRequest request, HttpListenerResp var result = CallMethod(matched_route.Route.Value, matched_route.Params); response.ContentType = result.ContentType; - if (result.Data is Stream s) - { - s.CopyTo(response.OutputStream); - s.Dispose(); - } - else if (result.Data != null) + if (result.Code != 200) { - var json = JsonConvert.SerializeObject(result.Data); - response.StatusCode = result.Code; - - using (var sw = new StreamWriter(response.OutputStream)) - sw.Write(json); + ReturnErrorCode(response, result); } else { - Return404(response); + if (result.Data is Stream s) + { + s.CopyTo(response.OutputStream); + s.Dispose(); + } + else if (result.Data != null) + { + var json = JsonConvert.SerializeObject(result.Data, result.Formatting); + response.StatusCode = result.Code; + + using (var sw = new StreamWriter(response.OutputStream)) + sw.Write(json); + } + else + { + Return404(response); + } } } catch (Exception e) diff --git a/Server/ServerBase.cs b/Server/ServerBase.cs index 32ca5d6..1c3bc63 100644 --- a/Server/ServerBase.cs +++ b/Server/ServerBase.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.IO; using System.Net; using System.Text; @@ -98,6 +99,16 @@ private async Task Startup() } } + protected void ReturnErrorCode(HttpListenerResponse response,ActionResult result) + { + response.StatusCode = result.Code; + using (var sw = new StreamWriter(response.OutputStream)) + sw.Write(JsonConvert.SerializeObject(new { + code = result.Code, + reason = result.Reason + })); + } + protected void Return404(HttpListenerResponse response) { response.StatusCode = 404;