From 63cfe1f2b86777f6da5ea177849cb2e4f8c5da06 Mon Sep 17 00:00:00 2001 From: Aplulu Date: Sat, 14 Aug 2021 23:03:32 +0900 Subject: [PATCH] :tada: initial commit --- .commit_template | 23 ++++ .gitignore | 5 + LICENSE | 21 +++ README.md | 19 +++ RankedPlaylistGenerator.sln | 16 +++ .../Installers/AppInstaller.cs | 13 ++ .../Installers/MenuInstaller.cs | 13 ++ .../Managers/MenuButtonManager.cs | 59 +++++++++ .../Managers/PlaylistGenerator.cs | 123 ++++++++++++++++++ .../Managers/UnityWebrequestAwaiter.cs | 32 +++++ .../Models/BeatStarCharacteristicName.cs | 14 ++ .../Models/BeatStarEntry.cs | 11 ++ .../Models/BeatStarEntryDifficulty.cs | 11 ++ RankedPlaylistGenerator/Plugin.cs | 23 ++++ .../RankedPlaylistGenerator.csproj | 107 +++++++++++++++ .../Resources/images/0.png | Bin 0 -> 2654 bytes .../Resources/images/1.png | Bin 0 -> 2640 bytes .../Resources/images/10.png | Bin 0 -> 2690 bytes .../Resources/images/11.png | Bin 0 -> 2665 bytes .../Resources/images/12.png | Bin 0 -> 2703 bytes .../Resources/images/13.png | Bin 0 -> 2698 bytes .../Resources/images/14.png | Bin 0 -> 2691 bytes .../Resources/images/15.png | Bin 0 -> 2700 bytes .../Resources/images/2.png | Bin 0 -> 2667 bytes .../Resources/images/3.png | Bin 0 -> 2661 bytes .../Resources/images/4.png | Bin 0 -> 2658 bytes .../Resources/images/5.png | Bin 0 -> 2661 bytes .../Resources/images/6.png | Bin 0 -> 2658 bytes .../Resources/images/7.png | Bin 0 -> 2645 bytes .../Resources/images/8.png | Bin 0 -> 2668 bytes .../Resources/images/9.png | Bin 0 -> 2663 bytes .../Resources/images/n.png | Bin 0 -> 2622 bytes .../Resources/images/pp_200.png | Bin 0 -> 3349 bytes .../Resources/images/pp_300.png | Bin 0 -> 3387 bytes .../Resources/images/pp_400.png | Bin 0 -> 3377 bytes .../Resources/images/pp_500.png | Bin 0 -> 3376 bytes RankedPlaylistGenerator/Utils/ResourceUtil.cs | 33 +++++ RankedPlaylistGenerator/manifest.json | 15 +++ 38 files changed, 538 insertions(+) create mode 100644 .commit_template create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 RankedPlaylistGenerator.sln create mode 100644 RankedPlaylistGenerator/Installers/AppInstaller.cs create mode 100644 RankedPlaylistGenerator/Installers/MenuInstaller.cs create mode 100644 RankedPlaylistGenerator/Managers/MenuButtonManager.cs create mode 100644 RankedPlaylistGenerator/Managers/PlaylistGenerator.cs create mode 100644 RankedPlaylistGenerator/Managers/UnityWebrequestAwaiter.cs create mode 100644 RankedPlaylistGenerator/Models/BeatStarCharacteristicName.cs create mode 100644 RankedPlaylistGenerator/Models/BeatStarEntry.cs create mode 100644 RankedPlaylistGenerator/Models/BeatStarEntryDifficulty.cs create mode 100644 RankedPlaylistGenerator/Plugin.cs create mode 100644 RankedPlaylistGenerator/RankedPlaylistGenerator.csproj create mode 100644 RankedPlaylistGenerator/Resources/images/0.png create mode 100644 RankedPlaylistGenerator/Resources/images/1.png create mode 100644 RankedPlaylistGenerator/Resources/images/10.png create mode 100644 RankedPlaylistGenerator/Resources/images/11.png create mode 100644 RankedPlaylistGenerator/Resources/images/12.png create mode 100644 RankedPlaylistGenerator/Resources/images/13.png create mode 100644 RankedPlaylistGenerator/Resources/images/14.png create mode 100644 RankedPlaylistGenerator/Resources/images/15.png create mode 100644 RankedPlaylistGenerator/Resources/images/2.png create mode 100644 RankedPlaylistGenerator/Resources/images/3.png create mode 100644 RankedPlaylistGenerator/Resources/images/4.png create mode 100644 RankedPlaylistGenerator/Resources/images/5.png create mode 100644 RankedPlaylistGenerator/Resources/images/6.png create mode 100644 RankedPlaylistGenerator/Resources/images/7.png create mode 100644 RankedPlaylistGenerator/Resources/images/8.png create mode 100644 RankedPlaylistGenerator/Resources/images/9.png create mode 100644 RankedPlaylistGenerator/Resources/images/n.png create mode 100644 RankedPlaylistGenerator/Resources/images/pp_200.png create mode 100644 RankedPlaylistGenerator/Resources/images/pp_300.png create mode 100644 RankedPlaylistGenerator/Resources/images/pp_400.png create mode 100644 RankedPlaylistGenerator/Resources/images/pp_500.png create mode 100644 RankedPlaylistGenerator/Utils/ResourceUtil.cs create mode 100644 RankedPlaylistGenerator/manifest.json diff --git a/.commit_template b/.commit_template new file mode 100644 index 0000000..434dd60 --- /dev/null +++ b/.commit_template @@ -0,0 +1,23 @@ + + +#### Emoji Prefix #### +# ✨ :sparkles: Introducing new features. +# ⚡️ :zap: General update. +# 🐞 :beetle: Bug Fix. +# 🚑 :ambulance: Critical Bug Fix. +# 💄 :lipstick: Updating the UI and style files. +# ♻️ :recycle: Refactoring code. +# 🎨 :art: Improving structure / format of the code. +# 🐎 :racehorse: Improving performance. +# 📝 :pencil: Writing docs. +# 💚 :green_heart: Fixing CI Build. +# ✅ :white_check_mark: Updating tests. +# 🔥 :fire: Removing code or files. +# 🐳 :whale: Work about Docker. +# 🔧 :wrench: Changing configuration files. +# 🎉 :tada: Initial commit. + +#### Format #### +# :emoji: Subject +# +# Message diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9fd32b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +.idea +obj +bin +*.user diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a7b4a60 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Aplulu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..aac41fd --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# RankedPlaylistGenerator + +A Beat Saber Mod that generates a playlist of ScoreSaber ranked beat maps by difficulty. + +# Requirements + +* Beat Saber 1.16.4 +* BSIPA 4.1.4 +* BeatSaberMarkupLanguage 1.4.5 +* SiraUtil 2.4.0 +* BeatSaberPlaylistsLib 1.4.0 + +# Installation + +Unzip the contents in [RankedPlaylistGenerator.zip](https://github.com/aplulu/ranked-playlist-generator/releases/latest/download/RankedPlaylistGenerator.zip) and place it in your Beat Saber installation directory. (e.g. `C:\Program Files (x86)\Steam\steamapps\common\Beat Saber`) + +# Usage + +Click the RankedPlaylist button that appears in the Mod menu. diff --git a/RankedPlaylistGenerator.sln b/RankedPlaylistGenerator.sln new file mode 100644 index 0000000..7182fa9 --- /dev/null +++ b/RankedPlaylistGenerator.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RankedPlaylistGenerator", "RankedPlaylistGenerator\RankedPlaylistGenerator.csproj", "{CC59A6C5-1CA6-4A95-85DF-08363B69A419}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CC59A6C5-1CA6-4A95-85DF-08363B69A419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC59A6C5-1CA6-4A95-85DF-08363B69A419}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC59A6C5-1CA6-4A95-85DF-08363B69A419}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC59A6C5-1CA6-4A95-85DF-08363B69A419}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/RankedPlaylistGenerator/Installers/AppInstaller.cs b/RankedPlaylistGenerator/Installers/AppInstaller.cs new file mode 100644 index 0000000..a1ff14c --- /dev/null +++ b/RankedPlaylistGenerator/Installers/AppInstaller.cs @@ -0,0 +1,13 @@ +using RankedPlaylistGenerator.Managers; +using Zenject; + +namespace RankedPlaylistGenerator.Installers +{ + public class AppInstaller: Installer + { + public override void InstallBindings() + { + Container.Bind().AsSingle(); + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Installers/MenuInstaller.cs b/RankedPlaylistGenerator/Installers/MenuInstaller.cs new file mode 100644 index 0000000..ef23365 --- /dev/null +++ b/RankedPlaylistGenerator/Installers/MenuInstaller.cs @@ -0,0 +1,13 @@ +using RankedPlaylistGenerator.Managers; +using Zenject; + +namespace RankedPlaylistGenerator.Installers +{ + public class MenuInstaller: Installer + { + public override void InstallBindings() + { + Container.BindInterfacesTo().AsSingle(); + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Managers/MenuButtonManager.cs b/RankedPlaylistGenerator/Managers/MenuButtonManager.cs new file mode 100644 index 0000000..c08684e --- /dev/null +++ b/RankedPlaylistGenerator/Managers/MenuButtonManager.cs @@ -0,0 +1,59 @@ +using System; +using System.Threading.Tasks; +using BeatSaberMarkupLanguage; +using BeatSaberMarkupLanguage.MenuButtons; +using SiraUtil.Tools; +using Zenject; + +namespace RankedPlaylistGenerator.Managers +{ + internal class MenuButtonManager: IInitializable, IDisposable + { + private readonly SiraLog _log = null; + private readonly MenuButton _menuButton = null; + + [Inject] + public MenuButtonManager(SiraLog log, PlaylistGenerator playlistGenerator) + { + _log = log; + var name = "Ranked Playlist"; + _menuButton = new MenuButton(name, "Generate ScoreSaber Ranked Playlists", () => + { + Task.Run(async () => + { + _menuButton.Text = "Generating..."; + try + { + await playlistGenerator.Generate(); + _menuButton.Text = "Generated!"; + } + catch (Exception e) + { + _log.Logger.Error("Generate Error: " + e.Message); + _menuButton.Text = "ERROR"; + } + finally + { + await Task.Delay(3000); + _menuButton.Text = name; + + } + }); + }, true); + } + + public void Initialize() + { + + MenuButtons.instance.RegisterButton(_menuButton); + } + + public void Dispose() + { + if (BSMLParser.IsSingletonAvailable && MenuButtons.IsSingletonAvailable) + { + MenuButtons.instance.UnregisterButton(_menuButton); + } + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Managers/PlaylistGenerator.cs b/RankedPlaylistGenerator/Managers/PlaylistGenerator.cs new file mode 100644 index 0000000..f3ab194 --- /dev/null +++ b/RankedPlaylistGenerator/Managers/PlaylistGenerator.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Security.Policy; +using System.Threading.Tasks; +using BeatSaberPlaylistsLib; +using BeatSaberPlaylistsLib.Blist; +using BeatSaberPlaylistsLib.Legacy; +using BeatSaberPlaylistsLib.Types; +using Newtonsoft.Json; +using RankedPlaylistGenerator.Models; +using RankedPlaylistGenerator.Utils; +using SiraUtil.Tools; +using UnityEngine.Networking; + +namespace RankedPlaylistGenerator.Managers +{ + public class PlaylistGenerator + { + private readonly string _beatStarURL = "https://cdn.wes.cloud/beatstar/bssb/v2-all.json.gz"; + + private readonly SiraLog _log = null; + + public PlaylistGenerator(SiraLog log) + { + _log = log; + } + + public async Task Generate() + { + _log.Logger.Info("Generate"); + var entries = await downloadBeatStar(); + + var playlistManager = PlaylistManager.DefaultManager; + + var songByStar = new Dictionary>(); + foreach (var kv in entries) + { + foreach (var diff in kv.Value.diffs) + { + if (diff.star == 0) + { + continue; + } + + var star = (int)Math.Truncate(diff.star); + if (!songByStar.ContainsKey(star)) + { + songByStar[star] = new Dictionary(); + } + + IPlaylistSong song = null; + if (songByStar[star].ContainsKey(kv.Key)) + { + song = songByStar[star][kv.Key]; + } + else + { + song = new LegacyPlaylistSong(); + song.Hash = kv.Key; + song.Difficulties = new List(); + songByStar[star][kv.Key] = song; + } + + var difficulty = new Difficulty + { + Characteristic = + ((BeatStarCharacteristicName) Enum.ToObject(typeof(BeatStarCharacteristicName), diff.type)) + .ToString(), + Name = diff.diff == "Expert+" ? "ExpertPlus" : diff.diff + }; + + song.Difficulties?.Add(difficulty); + + } + } + + foreach (var kv in songByStar) + { + var fileName = $"ranked_star_{kv.Key:00}"; + var title = $"Ranked Songs ★{kv.Key}"; + _log.Logger.Info($"Writing Playlist {title} ({kv.Value.Count} songs) to {fileName}"); + //var playlist = new BlistPlaylist(fileName, title, "RankedPlaylistGenerator"); + var playlist = new LegacyPlaylist(fileName, title, "RankedPlaylistGenerator"); + playlist.SuggestedExtension = "json"; + playlist.SetCover(ResourceUtil.GetCoverImage($"RankedPlaylistGenerator.Resources.images.{kv.Key}.png")); + //var playlist = playlistManager.CreatePlaylist(fileName, title, "RankedPlaylistGenerator", ResourceUtil.GetCoverImageLazy($"RankedPlaylistGenerator.Resources.images.{kv.Key}.png")); + + foreach (var song in kv.Value.Values) + { + playlist.Add(song); + } + playlistManager.StorePlaylist(playlist); + } + } + + + private async Task> downloadBeatStar() + { + _log.Logger.Info("Requesting " + _beatStarURL); + var req = new UnityWebRequest(_beatStarURL, "GET"); + req.timeout = 10; + req.downloadHandler = new DownloadHandlerBuffer(); + req.SetRequestHeader("User-Agent", "RankedPlaylistGenerator/1.0 (+https://github.com/aplulu/ranked-playlist-generator)"); + await req.SendWebRequest(); + if (req.isNetworkError) + { + throw new Exception("network error: " + req.error); + } else if (req.isHttpError) + { + throw new Exception("http error: " + req.error); + } + + using (var reader = new StreamReader(new GZipStream(new MemoryStream(req.downloadHandler.data), CompressionMode.Decompress))) + { + var json = reader.ReadToEnd(); + var songs = JsonConvert.DeserializeObject>(json); + return songs; + } + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Managers/UnityWebrequestAwaiter.cs b/RankedPlaylistGenerator/Managers/UnityWebrequestAwaiter.cs new file mode 100644 index 0000000..6b34f54 --- /dev/null +++ b/RankedPlaylistGenerator/Managers/UnityWebrequestAwaiter.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.CompilerServices; +using UnityEngine.Networking; + +namespace RankedPlaylistGenerator.Managers +{ + public static class UnityWebRequestAsyncOperationExtension + { + public static UnityWebRequestAsyncOperationAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOperation) + { + return new UnityWebRequestAsyncOperationAwaiter(asyncOperation); + } + } + public class UnityWebRequestAsyncOperationAwaiter : INotifyCompletion + { + UnityWebRequestAsyncOperation _asyncOperation; + + public bool IsCompleted => _asyncOperation.isDone; + + public UnityWebRequestAsyncOperationAwaiter(UnityWebRequestAsyncOperation asyncOperation) + { + _asyncOperation = asyncOperation; + } + + public void GetResult() { } + + public void OnCompleted(Action continuation) + { + _asyncOperation.completed += _ => { continuation(); }; + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Models/BeatStarCharacteristicName.cs b/RankedPlaylistGenerator/Models/BeatStarCharacteristicName.cs new file mode 100644 index 0000000..04cb59b --- /dev/null +++ b/RankedPlaylistGenerator/Models/BeatStarCharacteristicName.cs @@ -0,0 +1,14 @@ +namespace RankedPlaylistGenerator.Models +{ + public enum BeatStarCharacteristicName + { + Unknown, + Standard, + OneSaber, + NoArrows, + Lightshow, + Degree90, + Degree360, + Lawless + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Models/BeatStarEntry.cs b/RankedPlaylistGenerator/Models/BeatStarEntry.cs new file mode 100644 index 0000000..7f05dbb --- /dev/null +++ b/RankedPlaylistGenerator/Models/BeatStarEntry.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace RankedPlaylistGenerator.Models +{ + public class BeatStarEntry + { + public float bpm; + public List diffs; + + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Models/BeatStarEntryDifficulty.cs b/RankedPlaylistGenerator/Models/BeatStarEntryDifficulty.cs new file mode 100644 index 0000000..32a82d1 --- /dev/null +++ b/RankedPlaylistGenerator/Models/BeatStarEntryDifficulty.cs @@ -0,0 +1,11 @@ +namespace RankedPlaylistGenerator.Models +{ + public class BeatStarEntryDifficulty + { + public double pp; + public double star; + public int scores; + public string diff; + public int type; + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/Plugin.cs b/RankedPlaylistGenerator/Plugin.cs new file mode 100644 index 0000000..4655e74 --- /dev/null +++ b/RankedPlaylistGenerator/Plugin.cs @@ -0,0 +1,23 @@ + +using IPA; +using IPA.Loader; +using SiraUtil; +using SiraUtil.Zenject; + +namespace RankedPlaylistGenerator +{ + [Plugin(RuntimeOptions.DynamicInit)] + public class Plugin + { + [Init] + public Plugin(IPA.Logging.Logger logger, IPA.Config.Config config, Zenjector injector, PluginMetadata metadata) + { + injector.On().Pseudo(container => + { + container.BindLoggerAsSiraLogger(logger); + }); + injector.OnApp(); + injector.OnMenu(); + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/RankedPlaylistGenerator.csproj b/RankedPlaylistGenerator/RankedPlaylistGenerator.csproj new file mode 100644 index 0000000..45d147d --- /dev/null +++ b/RankedPlaylistGenerator/RankedPlaylistGenerator.csproj @@ -0,0 +1,107 @@ + + + + net48 + + + + + $(BeatSaberPath)\Libs\BeatSaberPlaylistsLib.dll + + + $(BeatSaberPath)\Plugins\BSML.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\HMLib.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\HMUI.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\IPA.Loader.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\Main.dll + + + $(BeatSaberPath)\Libs\Newtonsoft.Json.dll + + + $(BeatSaberPath)\Plugins\SiraUtil.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\UnityEngine.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\UnityEngine.CoreModule.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\UnityEngine.UI.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\UnityEngine.UnityWebRequestModule.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\Zenject.dll + + + $(BeatSaberPath)\Beat Saber_Data\Managed\Zenject-usage.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RankedPlaylistGenerator/Resources/images/0.png b/RankedPlaylistGenerator/Resources/images/0.png new file mode 100644 index 0000000000000000000000000000000000000000..88f85309a668c31ddd64432520e90aa0155e02f7 GIT binary patch literal 2654 zcmbVOc~BE)6ki5UP%C1UQA^VW!D^FDq5-lHC?p^e!*Dr(qoqr-AuF5gnq5f1Q4Xm^ zXH*#Q7)5bLixm*iGK>~Gh)1clrGkt~3xjBxmZDe`iy~^jO*jkI*UptPcE z4RIMPvKVpPp-MfLfJYM=RyTq+B3O+Z62?im=*T3l9o85KkdJr-EoMX}gFVHd5xFL@ z;KfcT8mVxd^b7m4^nQIyCF6-!WwaG6kw3a#;2w88vnFcy2AJ~stCAB`Gi36{hyH|tdR zldSb-y^;hs3Mh#g5@fKMuferg63N28M$C|iYxp#YrH}-}`XJl{k;EX7I>P^=uhL9?#NVD5mBrBZFxprAbob8Vi>o2dk8!w5$m;;{FMs zvt+QpR!e{yrtreJk>QC1UINKj1CtKt`s|f_BBL`Iip&QY7rQm_QL6;lS>J&b1$G@W zyzIbbcwOQKup^CN88&(eydlUYlK`zSt_2`yNp4bZO-Mla+&Vu3`w9z_%eQ7pV)th> zH6H1;FRq<&dTnpV?(-k+?#s`)ab(Ss?6v)prns=gYl|iYIw&ILOnAtZu5&Z;e_+o3 zv8B83FmtAFT}9UQRY6p5fZM^F0gg5|12hfzrtd>-`Chu6OTR^zdpZ}DZEjJP-cr@X zmTYOM(Z+4>vRkpje)rPiz4H&xJ^b0#5;w};wDiQEJN`aVu`^2iec1qh zdfu$bwT*&%t8UPx+xFz|b=bS_Zv8R)A0KS~X`k1f=BLuwO`7DRj`5k0pvcK3yU;)A z(zDLGy7YTr=RJ6SrEszP*&XIR@PZOoWp16z2LIwZT$Sy-FSkhd&r2%q@ui&dh*pR6 zBKM2tuF1d6%MaPslcIC#aH;UU5Lk7f&^x`|)DW`f=kMODpXpUyy5ZCZUTs-rQzgZL zX|5%!LtvY7_iOVqb|vc87x&)lE4aI9TKU!J^|js3y~=aU(}ms363SnO-|hrIYt!lA zSO$XZ9l6H_I#A#QLAK6Hg@2T};C@TB$~JuVrw!{BQ-fUrmRy5@0`5))VrYH_RNy56MnZnO~+qAXBKB}&AH8U^_n()R=}GbD=$BL z?*1lq)av#$Qi=5?9@xvF@8rPa5Dg_`VC; zTV^p7gw?FIu;2Dc&%mks1FhGq9zAtjIG&8(XGKes6P`Udbnn){$+SYhQ|;qf>!u^C zUZhp2ceOUObk=9iocd9%e=t3J&Z4YI?{Iu5=*SOAo8MTSH+|xGn)^fh+S=T)i{qWN zwAX*(-K?sZAjmhX@>qV}yg3ZQM?xw2(nGp4vF{1$YpisbAokaSS6)8oc0H&qxc#p~ gkJ~EWg~$FW=Zik}bSrxp$o(x;28Jri0zS|D7vSTbKmY&$ literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/1.png b/RankedPlaylistGenerator/Resources/images/1.png new file mode 100644 index 0000000000000000000000000000000000000000..fcc3ec3111a8ca1796864ce0d79a832e26978fd4 GIT binary patch literal 2640 zcmcguc~BE)6kqBMa;amjP+S)ZR-0@R zFrYY=5j(b6fdO?Kt0JYSEmB+SHBt)>TF0wckSU7VR{Cv%90gkWr+;knz5TuSzW09b zNVdg9M>yKgw1*(bQ4uMR1K%zDGjTllbX)o3W(XRWL?$G0Ny?>|iq;8nHJwTb%{l|X zAt-pE*?_Ck2@Xyr(n!4&>8PngU{Wnb68)4Sr9nn$$;eEGh|i2pP-Uj8g4D>u5c^;= z1{~-J4u{P;O3z|uDPr}DfiwRaMPRE6mo7z;lrgZ3W(e3%=qD5*A@*=Eqt;+?^2NQz zK$0R_jx%5=YBHIGCSM`Vq@m)VpdeHvK_wCa&=9Z|J%^hGde)P7Ve=s;SQSGWIFi=G zyiYupHgZw~0XW?2T&?Q!Z7?#F)w5cK5)`2$^c;(dg<^D|K4B*NqtUaybOGW}9s%m2 zLFyc-89|*#hNv5~G)J>q+Rzu&pey>|A%=kN;Z4lAVK`-_^54~UxyqM3Nm zhJ+LmTa9?`Foh0JBN9n9r|tLF4=g40X+sb`I?Bkm!*V?d@{#m=OX|m@NPq-1BHtud zf62o_eYL=>@hNFF2+!AQ)ek9TvKWTekQBh!xQH-V5iau=2l@L8Btly%pl}$lB{dc~ z&H*inNFox5#R8EyK^%xl{4vq|d7>apWQ)hD4dzFUbNGMh^HTr^t5q0Baui{eY*P_R zaW=^&QY1eL7=`Q8q=;FdCN#K_;*byq*QXO|fq}v;6v=YIC_h0I+3UzEz4jE04!R~7 zgsD_wk-&;(ECX(iCo%@#Y#l@xwze0BtN6-D5d%Z3jVeNI(O#_`J zMM5^?T!RUR*6W1|||&P*=4z@B=r zsl9tYd$N1gk=$!b7Sml}-k&suO|@$ZQ(qynzKtFu2-NPFdm8f%@F=U=*rKTXNm-X% zv8km_ld`SNe*S!iU31I#yuE+g{xugXylDs1+`|vIKRJ9PqR_#V8xnZcx+g-HBbx-l#OP@J>*Rk>Y;=o^Sz6eUrQm;QaH8lqkmd)_oS{l0e z{2z}R8nPdMQP}ZUW9fT7r?#7SBQqq5&L2<29f;({{mvmQF->G}NXxLdB- zWj^Q3ZR47!7e(cDTC_9nc^(Nl8-8M6>4NM#rYlj)f2ei7LLQo6F8S?Njq;mCE{kH_uGmePaBshMM%qvXRp3$K2_IK)6vxF=|7a_3(}SqEvint|DC(G@xIFn z&#m$BK9s>Vb>H=ja65Wuv^@p5`0xxV(RJ;Z=G2kcqih~sCt17hQ`66<-50#&5^$gY OBd7?EmRE(X&G{Rj0EX@W literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/10.png b/RankedPlaylistGenerator/Resources/images/10.png new file mode 100644 index 0000000000000000000000000000000000000000..c780599122ab49694c69b9a7f3064c740c9e8574 GIT binary patch literal 2690 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 literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/12.png b/RankedPlaylistGenerator/Resources/images/12.png new file mode 100644 index 0000000000000000000000000000000000000000..d1cd92e5c63e4521a386d7a966821519461ebcef GIT binary patch literal 2703 zcmbtWc~BE)6kkSB4$tCP$AhMef}>3~34&ysKp_E%7(|W=P8FBzhOBI|X?8IIYEfjo zrWL869Yt`e^#DdxrXENK0o!P8y$7|Rc#Nag2x^gt7VNhPa!9N?{bQ5w+xOn@z4v=Z zvNk4q)^LyU9uNc#S4Jvg!FLn)xD5fH6Be9Z0YR>bWPBo)){~t zf}|m41Ex+RSY8T|O6p~B>#-V`N8&Pget=4-GRO%n8JTG$;xeP-)tPB(2@Zz@dq~YF z0MHRE#xv_EJ%gHMupJi#XYMru^Xw{YnhZ`<#qi{`k>CXg0t7-h*n=lE;upa>nIXBk8!5Fvf_2{YLnjh^YI3lN8J5}+>Z zr_Pd^H>h)x0qO=V&C-mPHuMD5&qa@TfFYpUxrrGwI8#=s{##wA>z4+@hA#!gbr+#u zOs^a;@fijJi6t01-KZwQmjd>D?8I@rpfRMGpb`}%Ae8~tkilZH@HJ`Do1}7@qK$E& z4G9@6vKw*Sp-LT=O3Wv5R@;l#E0{y*QwK=6=%{qA9TM~;$Vc3Zme?zk!86665xFL@ z<0Uy2_0$5j$ETuk5T3u?s#m0x%VUhRhNOUuiJcY3Q-;d}MUuckzF6Q$1r!biwxlLQ zfw4eKEEEg*A`xFGiWdc;VhQT+KV2w6g^qaa+F*WgjK$uj&rJbOimOqUWGTXab4*1j z#X4?|D@AgnfKr$~RR){+IHAGPDHaYkV)`@!=Nl+2gCZGLif|J|k=;P{+bbj~($9?) zgsD=Yk-&;JX7uqKM||1evwaYGJbQbgn3}7M3^o{PJY7xTb}m5<4k<%xSQBO>LQ_F! z$>30ph6FXt;Kgtw!xIUD1OfdGOj?5Lvp4dI^v&c|WKv{6?2g3ytP)`7cn4M#*mX$H zvICc%bxG*Kjx>U0Xc@K09fDkPNYDxcS^$Ek=BMY^M1{>8V+kR#AF&v@d}VGx()TMa zUD)2{Sz0^n;DWY0dB;D>vlVP;*q$(T&4T9vmy%=B&P^N~K3WkcXXZtndQd&A;3RYO z?$<50V&;hLi~YG5XGhR&VZK{0hk3bN4#UqAS-(aP;s zyZq|S4_q6^7DTOjoS_|e$7g?VUHG9bC7&+8X*wU3@W;<1&kPSbR=(uGq@d>9eM19E z!?P!s&543tD*VokU9mn*yRfv)YAd>(1#M(=nlCdTPbXc{lEZpEY+w zWD)~Go?hJJ0&OW82SJ18Dixve=Aws9BK@V$#w^Ds+!>Ou-4isFZ;9T@?EGPEL5|la zlcr2Ra67x`vF)dMzLgDKnZLwU(|1i3D8*YxcP3Bfe|2*xf0pkv(*NeWBlLKi+jzsYp}OW9sjl%*Gre*oPV8u2 zQ5jM*;$eO6d&Sg)_RHraOU~=;YCJ5mJxk8J{!&|6a(1%s#N5F{Kdudp zG>rP7`*^P^>quqm-WJJ=;z!pzTROiwFWct+nhsE}YVmHlUVPV@RdqG1v@)b*qu2>Y zm#@_?yk?dCX_eh_=IW%kKB1l3jo0<{?+C?uGq`MrjcV7f7COOw&~j7rGUUpR?Cf@L zs{QY+ogE`noPac3tLIl)I?|q=Jv`Oxoyy;bv;TX1;gWhi!n?go{A9-Gwx@R=`K%6f z7US#m_o;;AxZb?`lvduHU-u-sb6cPjGTz!1+0b7P1)+;80~Or=NM(4mVqe(eoPPo2 Ce!g}9 literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/13.png b/RankedPlaylistGenerator/Resources/images/13.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd53258ae0ae0d4dde02efa96d270d4c9b32b55 GIT binary patch literal 2698 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 literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/2.png b/RankedPlaylistGenerator/Resources/images/2.png new file mode 100644 index 0000000000000000000000000000000000000000..654aa373aa0f4fd8165febb7ebc16f5faf82c77c GIT binary patch literal 2667 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 nY#ig=T(TVZz}Ew3aT(hO8vnG`pApihzt) z2Z0gMDg|fSG75|+bsSF+JW#9`S}h}0@o05G&?yoT8TxI)DOhcP_+yjr-RFIu@4b^P z(#WvsHgjzt2%0Vq4~_=kt?XlM2|ni~T+N1{DRE?M91|y5j>#xB7nf5>1lOR}0vv+; z0t{MQmO?Oa5|K=5gh(1Ym$i9=ZgsPo3C zGo<1j>MSx&U8|%RidItEVW-AiF$|A01nHjG#DHrjQkF>mU0tmn69&zMtO1D|EW#L{ zhAyCE)3gK{P0&=TPDX^R0oijkC63JtCM6AoDlV7=Nu@zGgor@Edkc+!7b>Dulr9Fe zAt6NgCL=a?m{^S`6DvtMqa0xy0hSY*h{24~l!DRYIwCL` zbe0eaR47PL!!%gRjttD_`fxqR8t9b-+h_00CptQkAe3k!VA%XZ)`0 zo6UQ>Z7b@h)g*L3&OiNWzOks_*4`BhHz&OIyqPFXx#l!E#6CDiL`OwjY(F`z=mLH0 zugp$kDSg!V)xq2w%R;H{papww2RT^W4w7FdGR{X%;`k`@+>c`(-Y(?_*0qYOewWn6 zS7x@>DH6A|+bmveo9|vxJiByO>DQMk7f`l(_x(?{KHq;ZY`d+^z1`_m4d?>5MQ?~2 zN4qKY&D@S#{l>dTU-P3wQVzr|pX0i@EHLzJ z-_yp%td4!#yZSGdeeQN_t6>K+w{pI?u+epOU_~P#+3d2juw2O;;x_i_(dc~*q1 zpI^B=0YtqD=6L+oxibUpy0ykr0a=@BI{Piw|9#kKby|=3SWmSJ%GpqGAD;hV$1hI~ z@LpS9?0&^I|3nt)p#QQdgfUvAX6-gU>I*KKrn?#L#uqL* z4j)>oNB*txN3ZtGEcvK;1XWA$-j!D7)RXx`$@!N4S3-Z?VfzU}dT)7^-+4>Q^J)tl io;tq{c=ms~tKUNW8xr8MugjhNYbXwh3_cL_P0l|Ax0PG~ literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/5.png b/RankedPlaylistGenerator/Resources/images/5.png new file mode 100644 index 0000000000000000000000000000000000000000..ff8b7572b74abf563eca4e242dd4f58fe6d38436 GIT binary patch literal 2661 zcmb7GYfuwc6kdE30bhutj3{mw1RqT{i2}(s0U;nn2*b+(v=*0SLspXPHoK7oL{J#3 zwg`+URv5Hn%T%DEw4+i51e~H`ebw<%v1%QsIwI%{%7|s`-GpZWi$6BGcfaqPd(L;y zImynb$k1ty^Bf@vnx+T~jsf3o+%x4P@aeYp%2o)PoIu7UunEctOhxJWxSC2P_+~u~ za0rqHm}y*peEDoFXIs=25Wr)=;2G-nb6oIW2HdTfsD5GFGWh7u9z7Jo3_&dT!Z-IajL&eA6bQ&gxmMLJ1wACk!lu3i(2GD4#HsgV7k6KDmH!D2D*L zU>KbxHDk~@WCWeoQY^)2DS9BNVMh$WBMgDuqnnsQ>$`+u zG4&t7#93$pjUgDyWKe~$VW8jEnyIoA$}rIh+L6a z{UweH4crB0jZaCbL3qopR)dg2E{`%&8d3)^CMGlpR)olXg%V$1o``Qt1za2kY)OqJ z7-s=XBoGOBLLpBej1!76ksl@$FB3>Gfh`^@8}yGFXYv2zb6o&S)hdi7Ssh{B*}5W7 z$J%zbt&Zec0n_1z6d7XXsR<2k(y@rY5jUg~Y96h_Ejp56r6|`yIu`pmo87)IjjwQYrezLU@Vc1$;7_Q=OMuyNvN^MdRYO9tY2OG*z8a53#5`ih8 zvSdi0Mni%-w7^kZ%fLdunC~;(AWchfbvCA+=+I31Ba@;dVz(teWRw6q+dD9#z^p?D zh8@@pj7!1*W~31e!)!@B4ncO?NKgtRN&tcu7n%wi!h@n`w*-**_jr_Co|Eg7xPR-7 z>xa6WDjKKOtnGT7e|BMhcTvI3Lu(fASli=sBPlBN>ikI|&cU&ACOZ7WvolkR&NH=t zZ|UeRV@`E{b}aYz)vKtkAg_{JK`wT;g4EZDj9()s^2FM_rN3ay{oKosX0|D+ZYvuS zE4Q>YXp(k5b6l~)DSv6jzPV+y%RX7mL7Ss>&1~{p?jPh?;l97YC^rdm;FQ3 z%$Yv9@jAbK^-a2J``)5`&ijfVUH;DLVrS;1V)0*h-bfNN)SC{wByWTG<*pt(4hF6| z_x5Q^OLqGYdpdhB99-mGyUV;6nOEtlC~WcA7+BFlD0jFQ7nW;ZzoU{~ohzu0x#yf+ z?%iyDHu>(HqVVl6En3&d9>@HfLQWhw_-XdTv}@sOeyf{td7Aii)yCrs#P@TL+WS<5 zWO-Ibgd=v<-dE>r-JPmkU(waxUHT|vN_A`e`o<3TF2xzGQVZ%5y7cu8elOW;e^h*;EkYyTmlJ5O$7gyk|RJHF+Ud7S}Y z*9RJVwtOSqowIJ?pDp>N(o4BH1rK0P@f3&YLEFZ=yoWYZ1)J-XWhXvqz0&ex>-;-i zZsKRnZ?y}(#v9Cs1pYp5$I1G$xHQX)jf^#!(c$)2x)73_abo z{(S0B_7S7UwM#blD+l`}A9ly@lWH7Q^6e|flrpawZ_`Vpd51GLF9g6>EZL9tUpE(pr1Hq;q^|qamRzFxLCe~`*)}ai3~m(v|-!7B~giw literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/6.png b/RankedPlaylistGenerator/Resources/images/6.png new file mode 100644 index 0000000000000000000000000000000000000000..1a3e950c122d07b68b50b7dd82ab2d7a36f03b59 GIT binary patch literal 2658 zcmbVOYfuwc6keuM6nvE8s3VH$Lcz);n*@2S1PTdAgixL%IJLNBH)JKruGx(VPX!sD zwa9>?RzYn`D^RfNv33_TH-5f!h@NK^Xba8RIqfC&Wz zT7t!RCap%tpe6}y;YGokdyT+6iwT=1ffE(cJSn9oc-{hUfe;R~=LP6-6&foG>vsk_ z39M#W8buJJ(I_x_2`GIkBJ%h5M}%TTEan3XK9jCvF%w_MxN;O$4jI8H^(4)bl#a)7 zVkwk?mB28-dHv+La)6sQ=rtB*T!|1GLQCja1`!EF$cy%bi5!eZ$MnkughMz4m8p5Y&((2H;_iK<<%UOc*_qu|o0R=34ELYcOo+N+4W+5{AU| z`~W6CohFc2f}sq0B@wz3sOM@Cj?)E=CQXDUQAPq$8ITPLEEWs@g(i)LN+}Jcj{{{$ zNMMo0iPH|1Yq3;fF^RM4LAF64lF+3NL%8TP2Cf_ubR@Wsc#th|5R<^ZVo-=&ky!YW zMuY}(fm-5IP&f$B%i=W%$)(b0J*6Tw0ApeohVbN}QXi4Oj}KoguwDfu4h6oXDqV)L zz)CC>3;7}uUnq(f`JrN8)Jy0o^hbr(cr4bSe{hV&US`jA0WSboqAba32+Pje6~P+T zy0dOIB-aY42GgZVU=trFRG2}-!hw2Bmqy@xT7#u)NQMnSxDL{g{X~}CbEW`f$T0yR zOoajs2VRsu{e_d`h!sOmwlpG-XDKffQ*xP+z_gyi4N3yHXbJ9MMHx!P8ZkW)oC+#S z0tc&9B*Fp}`c20r0c*~_d33JykdE|XDIXdm!tZ|`^vN$Od6LF^d*u>(~%+Z@U zcg>~D5%c>8^4k}MQN1DVA9sW}*>r^9=ZVZyQLpj+)SKtkqF%l(<<;4p@~WQ{jY*X` zosFvG4c+$h=Q|Y4tJpTZbZY4bt(ESSgK^&eTO04~Kd`XK!T##bjH+hD-NW+~>z!o_R$n)sk4X5Te#+TNesxvLznblLHNV=8?w!{224l`L1Vb&9j(mx53Za1Ufv4 zfglGb?y-S(?wSEXufcLzaJ*^PADyD88_`qWjd3RI!so|VDSuA#;dk%Z7rbwo?cN<3 zc_;20=(D72cHQY8JxiZ-bUoT_&auhaYUr8%pscPw8PaXI#&h!d3^tOvh`qA!{j-q z3l&#$5B=KsVIS5!c9vH;aa7w|hs_T6+S;!)w5`hSG(Yrh&L6JE<>LuCwW)_Z7L0Qm zt`NED78rFEV6|Jiedav}X2o5{{Z>Ujr9Nk literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/7.png b/RankedPlaylistGenerator/Resources/images/7.png new file mode 100644 index 0000000000000000000000000000000000000000..b08e86a587c495819d2188f88ba58fa25e2d27cc GIT binary patch literal 2645 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 Lk5=ssTblI`qAZ%v literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/9.png b/RankedPlaylistGenerator/Resources/images/9.png new file mode 100644 index 0000000000000000000000000000000000000000..f51da70a17d9f3a95f9afeac3cc87a940b950e86 GIT binary patch literal 2663 zcmcguX;2eq7+yT8fLN>!I)b=es92n2lW-+l0u2d5gdlQ^z-V>JZjzNGyJi9isect=s ztc{P0a&wvN0zr_QI$D(gejE8~^n2j$nfB{S2pX9}C8cmFnpjLrn}j$)r;|dfi2*nS zg@#)hT$@31a5|}{%yOjtL=^&4gdCY0q!DQtC263dvn^y|c3hG+J3}iYknk{}?cNCZGaz}n0lZWWkWAD+U&p(0tWgcQvKeT*`9QP#GyO_#6<(d zIZF2$aUK~Y&KPKpW(_pc=hOfbeefVfknW*XtT;22utxLW;wIC8Fjy{f2}oQ|5eE3w zYk*C%F(jHmvUH|JOGYjM+4Hd{j?W7gPgzN0ii!eBWkEIMh(sd#7n=GyR7o3YOCo4P zQjUo2N__4xwF%dgb18x|^t1H?v7}i)2;sdmX7cTjY^Fdwl76<7eoT&pNI)a>IhBi2!9~oFIlnR3eDr6Z*zRzBpPxRGDdOZt82l?&@{FPM#^c?TNiUPY1?OS%> z(6=s0GuV+9undKN`X7cMr#uR@!k`v_py`E~g;g;Tb0*Y=Q}{P{yi&O;KPYwk$}5+5 zces{Sk2#dqac9%%shc{B3hH+!PhXSvJm|`T_>4*)u*p4-%G6@>#P>G4t$; z`?a+z+P>S|-gR!*M}EiFS+^jQ%YD^_wLXg!WwoScjrX>~Qp3}3dcl*k1r-TR<5raV z)mU3cUiT=9S^d~%m~_YIK-ihc!#j3;vf@@&T}<*XmG574lb+bO=-?D-bN>EOL1mH4 zeamBG5T^>iOCBpXW*Fv|b+mOBx8#hjxG;Bq^+WFt^-1=b=ffHLitaf#?}N{pGZUT4 zLXhit{&IqL6izB#5aZOWr$1(kgybLqB9^z?G_`io)BwuTqOnAsyneORrCX52sU%73%RdmioK z>rW{x&tA%HUVca9l^dqYY}=jRmIj#2o>xN`EIk=la=89^_SCR~fStL+^*Py|4{GvP z72Jex7?f0(zT}>tC z{5OvJFL`58M)Mb49XWw<)k8#gttREsExttXWpvI935$X sTzc+@x{w5ErLueW&bMgN-iH2ax%+M3aKcZP!v8;1N5-l4M=Z?y2lfAw1ONa4 literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/n.png b/RankedPlaylistGenerator/Resources/images/n.png new file mode 100644 index 0000000000000000000000000000000000000000..925c45bb1ff99038e292cabb739fc7f6f79145f5 GIT binary patch literal 2622 zcmb_edrT8|96uBl!N+{WG4XL;nK(&%ZLvsiEsQ>Zie=?t1fpX{?@CYFUhN&Ug@}U8 zXC@L+Co<7&;she7$)Xd(P$NDzQ86+j2Ang_;KW4+QB?N37I_TZaPg08f4}>Dzn|~> z+iupyL{9Xc=?y{9L`{?`4tzIrkJni6>6hG)3qfNNsf0u}QM(k=(`Erq(5a-rVYUJs zf@EP1E3Qu`SvZwUqbzcy{ZuUiQ-mB@F3}3LRwZeqqOxpcd{#_?J}X@>C6KUCZb^eTg! z95J%26+=kp8Bh&5A{Gn(fhN5PRnjKf77yBx zlp`XS5|=wnW5(0S$0o9DIT_;29|X8IF{UTzu?EY1zknkZ|+~VU{msQ$&D0U`qf#U>M5#tB@-Kcv8`r8(FNw@gPg}* z`aGhOExBo}+_1A~*OXnm?_K%U=TiHcpLU1*dh3}qDVxarW?E_7myjc2Sz{xF+oyg1ze@$UMZ&i4CJ*nL^XLn(lv9pIx`Rm;Fs<=B-)|CaE zb+nDSJ)%9dJ?(!lh9ltwrf<9v#sVB4jn;I`rjf>W#jGat0M6~1v&23P2SN|Wj zw~M0BiFc&NCU!$xoju9jo&_gs2R@{9U^`;z|!^`01#icHYL7pYjeJwO5s%jhtjYx8beY$4$y#edwZ5*&c;= l1;5nZ9-5~CDI5NHU~Ze=2RxqQc_sI^Pos`e9Z`Iq_ctp#gJJ*x literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/pp_200.png b/RankedPlaylistGenerator/Resources/images/pp_200.png new file mode 100644 index 0000000000000000000000000000000000000000..a520f6027a6baf61db73b9109bfec281524b0466 GIT binary patch literal 3349 zcmbVPd03Kp9;athOS@*Yv2~mzET`50MX_W+$H4N!%p>tAC3(SDk(apD%Cef>$+2cu zt4XDF+E&H1!>q*8+@>1yF?9+p70WAfy(&db#@rV)kF>VkKVIPX`+U#O_jn(^_wnAc z*wD-nfj}&Fccb{i-%Z+Qfj<2CWpMQY1VS$a^rs1ER4+mV6oa8Npj`k)62paY1cK-+ z;nE|b0ReIszydiWR9{IM3JEeus6af`hRP)ak)T@~5Acig_K%2*j&Nk4oSh7b5&~=> z1`yDZk{C9JPmqvMI=ck;xAq!~Lh3{W(Iga&>VqUhJOGKu;4wBRCqpEW$6ykCDVryh z;S&iJDG+c8Sgcqq#)$1O5RZkmb#!#Z+TgG_92%BD^J6&zx&+PPTWU>=+n@ma2p-54 zfDi|%wMpLv2?Zn+3dWHW#u*Wlwz)zcTW6UOfd$w=48Rfav9=gn>~wiR0!~H4;ZM*7 z6Nl9zu(-_(aRJEufVdW!CC-h61Q0(G;!XxN!^I>#OA)4fZWRfgJC`t(`f>4?m>FsC z1+F5PxQQani0PdJzJDwi!1@AwNXUx-TtzT@mOA3Jybydq3BaaNK$uiMTn!QmhqHMP z4f+sDhS(6#4{k$%gtFBsX}Ke~$Iw|oAjl9zPFb4*yZ{bs7NU)gE!4I{00)Hg!A)7C zO<^R|1{~ao+9uK23z`#}tOY?A9~EN2;o0f5rXY7R*@p))K{kx>eYb2vy1SAcY#kjO z&^XL^DsbTlurA1qrO*Yi6wU@`gSNFr+t~TrIuh_W0^Y{j#*tt%9*<5Mo*xEXK>u&@ z+9^O184&~lC}0D+)A&@lum$6%@gp15jsk&A=deg937P>g=|Z*u<;0_Nq5%e)%cjS& zLB0UZo5X6LR%aX zipzr-!U%w&qZ3YJ9OXkyftbz%Tv%{(kx(v7CJ2`?7U`p%8l){|BL+WHK^zHaTkV6C zVy9>FE;1r^R_x=6PunK2-uNB7rQmgko!ocuVRB;v9C%Ig;C+ZXaHbQ1n3o8`-7u>Q z5Qw!u34bc{+_cT)o-??OM)x6;4^r^J&n}OC&rH=*gzE>PM+U%W$L_^@xJB3e#e{+$ zHTyR<2Oqg4@s|a^}jv+VidB3-mvK8JB#(qf)9OdLako7)u_5aWuGKI zRFcYAZMDaWm{X~DxNkivxFs;jc=_9_w558Z;a$r_YxeCPFtv6kq1R)xvC{k23Jnbl zCb7OST|IbYD16!K{Yy>lyjofQavY|AE$7CfiX((Kr+IIQK@|avy0w{wn-f<%>bq8X zs;^T52Cn~LqL(+8poz+{Z1zw)SlE-&pT|4fL*(4Zw6HDz3?k@jj6<1GZ=R4>XqMfi zJseqbt9YR*5RaA{nTFJi=C}^H1zk>R^k3fWokdzC-SCW-J8)iJUGb+w4()jbbjU)# z{RUrca4L~Cx(Ceq41TjMv_7)po-cxmN)mqT%#u34w!x~U|I$^4!>&gCg5QNtEA=uXPlMy*)`vgIa6R#1Z1 z1hBn2{nCCVuZy)wXJ1XJc4}8Anp+jxm07HUn9M>uFkmdCS3Q5l+Wehc!|g0@oBe2QdgFr6&F3#%k~rVMf>)Mq`NWXsGM#y8=hjTDd0B1O zpU>m@jQ9%{18@3JM`z~Qe6D-5U*Erq;>DMgL+NJX8kO@c^OpaG4cPT>Up-Ym?o@r- zJ0Pt+=rlI(JtEq7+~+JBDdElm&8EECcl+YEEF*)xZ%h7W`6<&rT9+^%kg z>}=Szurg`a#r%S?ea<237n%oGmFy;I20yAP-+VMHs=MZHS6ZnkgV@|uDw7FcdYskp zJr=@!n%N@%E<_$6)Km_3S%gNHaoXJ!?Qf2Eyh@QC)7Uo_oarB~kbUoGU1<#YC+Clh zL3~r$3C@5hRPMkiSLTdlSC*9|dj(Q&N}q~GGnQtA4J9Q+^}PP$PC&UjGF1LN^>gh! z+!lHiAJ5$?8!Rh*C9fNP-uPgLOg^N%|GL$S-)|-`?(?UX*6$mA;ja;D!t&x;(g(X( z&XK)+2lj@G^{%OCiqexMjiQ!%S^UW~Y4ybw(%!c!0^!YYp0ti4*7W#!uUiFApnX$z z>Q;XI(Z&G6h6H;5u>)(I8x*SXezXtGP7P6>E^Iy+COculxxs0<_Tb)*(vm@kpR
6vPIXPCPgDh}XDBP^dT`Ojq`T+P*{Pqrdp^+ZKG6n)PwL0=_O}c+oyrd@ zq$WGG{-4{(oA~e_V6v0t;jH@lvWM@ji;u0v>7k7pcs$%dy5;|pq5U`G?&?h`*c6`l EAI@PS`Tzg` literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/pp_300.png b/RankedPlaylistGenerator/Resources/images/pp_300.png new file mode 100644 index 0000000000000000000000000000000000000000..7c43fe77dc79abe444062161a14b9b00ab972e98 GIT binary patch literal 3387 zcmbVPdsI^C7N^WIEv=iAt+Hg%!^(L0Km$QjFkfMgL28ytaD9 zZ>E*atxQu}nTe*6%}uX0rsa@L_^8y(Ou3ax>L~YsrFpHH+x&5W@B8ij`}Y2Qd+)RO zE-=7*zUfj^7z{Sw*M}SgeK+eLliAScvK{r`z+lElBLfL|6@VO{DlfN54$+!Xt zhrtN$G69_t4T#~p0T#$3A~e^P2sp?jB7(6L3`IZ!*q~3G5ZD$MKxM>5GjL3VyPGLN zhKC5afS3-KaXCB@UPeS1c=6D0{Wcl_H<*Z{iHHzNAe_V(0&pw}i^3q>OyL9}GYTI> z-u&JfS`iU!u~>jdqhn)ZQL&CFzL15s$Kh~jj04)i0SQ?kMRJ~)E<^G}EAHLEszK~24*G$4R8Q1z!Qtm_9%Pw$M%2>oQ#Gi zdM_6w99oY+=9nqwVle76=6YnBxq!_V^F?gFU?Qj~M@+!e93ilt_x=*5#Ps0+5mhb#&_RHRFA*{TFDaznN`r8EUGRaR4B&*2K}b{)bQ?s3 zg9GM&(9qAJBtC~P+y<2)Kt$LZob=k^eYtcN5DYTK>`AssU<<%wO+)n2aU}Y3pz%N` zABRb{kV%Y)aB+YNQC}nmzR*uX6L*0(#7E&Xq3|3HUXze7i4-X0M}Zs&69svD!hO9+ z&h|KGXQTsaJQe8T@Q^PUB`4Fxkd*_*0fV%+M`9eQ_BcG&0qY3*LMM&z+~XXpqK*~R^wga!4Z$I#+MvW-wJpRoyQ^~WJo3uMVD~I2sa^}7Y#6x z0uEiy0Yze@KtMq2n}`Fx=Q6B5kP*;RP9i{&QYd&I$dNCUe{}dZAZF^}hF*lj4Hbr` zGxV23LREJnL zpf9!0N{aqClMj&*(9>ccPyC~40{M;aK~oAEcj$?E2Q4NhCcuNnq!5~im>Lxv2Ah!r zLe(&>3Sh9cMN6T(_F*6bH|)?XF6$ zFR=`lVwDYP%jf(oL!{-@A-C+$jXte)3VHpItIA92i-=CYJ>Pigj#OJqO8wleX7z<# zP6uOCuODZwTC;ZzA@{EFe$58rj;Fx~7kxE$EyTijG_q%bbai4(zm=UY5xD_<0iAuv zPBjvO1`o0pTdf*Q(?%{>m26?sK7IG|ty0jqJ%?+3GjoY~w^c`8?j;iBG!7&W!LrABvwnvS?@2o}u4J zOGXw{hBOYF-z=Nk6^uoen^}c5jOKdv`-EOOsHT3^8jwSrm+kT-k%ROgQT zLOS1Oc1MM1V9tpY*63a^XCd@vn=9}M6~SO;i}cS7SZ3A|=uP;}m+V26W%ahWv$G`D zHLo?RLGC{6kIv6*$m?IiO%N}hojr4m;UW=O?krc7sfQnQ)bQaNZALk^7#G<+()or)kc%Q{n7U37~O&G8jmZZ>PD`4&7qzw zMZ@s-T=VB9U&Qj^%m&Yry%s;%b*Zfj^0p_j<(r~H)!Lig5a}M9!+##k2b$@jo3)4E zByW^}&2}#aeoh!sCp~UTO5S*DN|N#n;Sz48SyO-C?nY%PR&%u|DGfK(sZ+FkgX+YbAKj(+1T;NH@ug}FLKei>U>mBYs%GOO_@#i-8H{w)4aFFmb%<1d|aW>KCU5Z z3YrH!Rn13riLa_V^LkE~IM!RfpsJ)Njlywl&)KxQ7Om>OWXj?dMdiAmp4TKL%uy)e=)aRC2poOH*3BbF3)q%xg!RmwsE|U-{PBwNY!Mt8MKq5nWGN)>tvG zZry5qi=Yym>TPOPZ&50I+E zHI?(C#$>9TUBNi(xXaoH8OnRX+#+-5!SD>@^yu(!ox`f?PUn@6^p0!JomIsRzcf5F z)F;*TD9<&zD5bBu2HIYhJ#X@E&&3sD`mgz5p$i)PkBLd*LD6ePw>~Z_=g}$|EA50_SIcab~UU10P)5 mt~q+^my<7ajel`WjT-&E$N6MOSZuNWKaa0h0J+dJGUdO`COn$} literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/pp_400.png b/RankedPlaylistGenerator/Resources/images/pp_400.png new file mode 100644 index 0000000000000000000000000000000000000000..85a0b5fe21e4c304121613ec0707f6246e0fba7f GIT binary patch literal 3377 zcmbVPc~lek7EYf60*ba$vDius6jYi70s#{fD4T$QA`l1^(U=TjAj!lmB&@Nh?;TgF za2|pLp;ly*=Z3P1N=rmVs0c1>A}FFP2U!IJZzd?nL#=&(OftW@_kQ=@?=Ev@pXVm$ zMOyk=C=_autBa!-{NIFJ3)JD?6#+Frqflx;fj)E*-NT*Cgt#~c3)%tTq+C8MN1-UT zQa*zj28hr*05-^@V){zTF=&uQ#rP3D%sluGKnUm(DFD19H~BCl!W2MO4Ca}tS!HzVK)1T3t96-Mwx3@Mf;G(;e#FdP9PQvmWs zAjCr>n2a5eSVYBOU^)6NIEy)r%@+$eDr6QD4{!i3z!M4a<~Vcw`}%+soQZ}fd`lNh z93GLt>SnXlMPTqp)Dg)Xb$$pWf`lOue>$jHE~dqE3}L!IY$9dwKcwv8@o9A~cUBrg zkyAKK+}k3|is_vLp-%)Kzu|)`29gi}X|<11 zihnb7G%L{Jm`g+f6-#w-mhY@YDMaK1^>+fCsNh0lW|G0u%S4P+!D>a5v29 z0u*ZX5%H07H~THR3R`dso#E-=u-lOc9J9N3H$73Ue!IFqc5D!Q9IuGl=n_`DR@V`$ z)PI4`B8KS1{kq`S?2MwUQyt=g`F6&r1v*)>vLqi+rke0u}DonV2_EeM~&uY?V9{f%L9@< zC5bE}<7i__)-AQYeLqkG+WZbI{d(dOeX*Ky`^zQa-^cD8)H8LZVt>G&#>;P-){oQi z-~skBJ)`0MBiol4?OLp7;r@i}Q%t}Otmc(2tlCe0ohF!|_*c z4HY`l1`7}Bs^w0~#zV6VTQ&|^8CX(}KZ~-pgdDO%Qnoo~`jgeimj(uhzJBPie0)h6 zy>3kBYLRBA9}!!ut@l%{GRtYu#sB<)MxU=+Hf2y3%B>&Mvj_8vYpUk$vFgapXFvw( z9i_q{jpR7CG8)YI5`MF3@?HFeD3tb6q>8@@H09RPdr|A|ju*+sBfhkOB>k3E33**nk1r0N;9gwJ{>+d*lt6ki!{Dlm zwENZB`1Hn86_b7a?XhpXfB$Ayem6=Il_4*-76$dM;g4>}n3K`~X19scuDKxwdt$!nQKC?bB4h+Ilmmf0EZ$XfUa}^PhjeICGh(i!prQ z9GjOyI$NNa=-*O*J$s^(H0ock#B+PjUA~fAJiJNPe(+}DV8=qF?&)2{zcuyS*Wa$_ zdD?LJ+QAFT>>PQ`#iS&NrW~jni|6*_JsNUUTw3hgLuv@R5|a_y^&}*|BzY_3!)+{^ zC|>WEv#f?_acB9l{Kv!c2V-F=QRd^3^*@g^-jYT8h?S#b@p6*a(2e^&PpQs1!_iG; zJ=d3=7_HEkSp3VTTN&`WK|;HqX|gUU5oySjZnv9qykGN3fZ|nq^Ghg}R#19&Z2VFg zZE@+t)^&|Ke%12s<(*Y$ppxh_FDmt#8}Hb(2BpQE3(ahwlpVLF6+}lAw%@&6rNg^_ zfi~XqqAYfzE@!=M-h_>?V`bd>!v1wD{I3KKu@x`#%S`T5`cL!)1&x*(7Opzv)*9$# z57QZP9=GPQElvD9;qcR#=9itD{gld>sE97FXNAVi-HkM1-*8a*aBD_gT4&D6vCNUN zT$7Y>3V*)4FaONLoaW6VLFJ=v^{uCc3JdHdgQn5Gm5g4jmeH)~e&R-K+FYvPw}W0(EgyePijLlxQj&N;`Z$xuA~L5K!t> zAUYY97u3#c^(#2Z)UQ3PC^>!QjW9D5hz(N^_am8W@w#@@L;o4R-1DewZCJIeWn6so z(aw>y?$|PG31_G?e{x_9(p8*-aBEhBqd6)TXV*gWi2nEZO>(`);8J2Lr)u4Ms;qSRP~-wVTtcE4QnyGKd}DE_HgRa z_PYsg8$WL!&29O2+bfH>D<=f3r~cgVS0nh5C8+;9)gz_hIo0c! i)KHlk{{PM9bK8V_CJdcYZ9U{m$JJ?*W4`_Nxc>r&wmkd* literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Resources/images/pp_500.png b/RankedPlaylistGenerator/Resources/images/pp_500.png new file mode 100644 index 0000000000000000000000000000000000000000..3c6b5d7d1a70103aacfe291fc94db73331904fb5 GIT binary patch literal 3376 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 QX!@fQ=ojo;?6XnzKZJlOjQ{`u literal 0 HcmV?d00001 diff --git a/RankedPlaylistGenerator/Utils/ResourceUtil.cs b/RankedPlaylistGenerator/Utils/ResourceUtil.cs new file mode 100644 index 0000000..2e30bef --- /dev/null +++ b/RankedPlaylistGenerator/Utils/ResourceUtil.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Reflection; + +namespace RankedPlaylistGenerator.Utils +{ + public class ResourceUtil + { + public static Lazy GetCoverImageLazy(string name) + { + return new Lazy(() => GetCoverImage(name)); + } + + public static string GetCoverImage(string name) + { + try + { + using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) + { + var b = new byte[stream.Length]; + stream.Read(b, 0, (int) stream.Length); + return Convert.ToBase64String(b); + } + } + catch (Exception) + { + // ignored + } + + return ""; + } + } +} \ No newline at end of file diff --git a/RankedPlaylistGenerator/manifest.json b/RankedPlaylistGenerator/manifest.json new file mode 100644 index 0000000..fe8be32 --- /dev/null +++ b/RankedPlaylistGenerator/manifest.json @@ -0,0 +1,15 @@ +{ + "$schema": "", + "author": "Aplulu", + "description": "Generate playlist of ranked maps by difficulty level and performance point", + "gameVersion": "1.16.4", + "id": "RankedPlaylistGenerator", + "name": "RankedPlaylistGenerator", + "version": "0.1.0", + "dependsOn": { + "BSIPA": "^4.1.4", + "BeatSaberMarkupLanguage": "^1.4.5", + "SiraUtil": "^2.4.0", + "BeatSaberPlaylistsLib": "^1.4.0" + } +} \ No newline at end of file