瀏覽代碼

Merged in fixes from Downloader.
Version bump.

Stephen Damm 6 年之前
父節點
當前提交
52052a5258

+ 3 - 2
SongBrowserPlugin/DataAccess/PlaylistReader.cs

@@ -102,8 +102,9 @@ namespace SongBrowserPlugin.DataAccess
                     {
                         Key = node["key"],
                         SongName = node["songName"],
-                        LevelId = node["levelId"]
-                    };
+                        LevelId = node["levelId"],
+                        Hash = node["hash"]
+                };
 
                     playlist.Songs.Add(song);
                 }

+ 3 - 1
SongBrowserPlugin/DataAccess/PlaylistSong.cs

@@ -10,10 +10,12 @@ namespace SongBrowserPlugin.DataAccess
     {
         public String Key { get; set; }
         public String SongName { get; set; }
-        public string LevelId { get; set; }
+        public string Hash { get; set; }
 
         // Set by playlist downloading
         [NonSerialized]
+        public string LevelId;
+        [NonSerialized]
         public IBeatmapLevel Level;
         [NonSerialized]
         public bool OneSaber;

+ 4 - 2
SongBrowserPlugin/Plugin.cs

@@ -3,12 +3,14 @@ using IllusionPlugin;
 using UnityEngine;
 using SongBrowserPlugin.UI;
 using Logger = SongBrowserPlugin.Logging.Logger;
+using SongBrowserPlugin.DataAccess;
+using System.Collections.Generic;
 
 namespace SongBrowserPlugin
 {
     public class Plugin : IPlugin
     {
-        public const string VERSION_NUMBER = "v2.4.5";
+        public const string VERSION_NUMBER = "v2.4.6";
 
         public string Name
         {
@@ -25,7 +27,7 @@ namespace SongBrowserPlugin
             SceneManager.sceneLoaded += SceneManager_sceneLoaded;
             SceneManager.activeSceneChanged += SceneManager_activeSceneChanged;
 
-            Base64Sprites.Init();
+            Base64Sprites.Init();            
         }
 
         private void SceneManager_activeSceneChanged(Scene from, Scene to)

+ 1 - 0
SongBrowserPlugin/SongBrowserApplication.cs

@@ -63,6 +63,7 @@ namespace SongBrowserPlugin
 
             AcquireUIElements();
 
+            StartCoroutine(ScrappedData.Instance.DownloadScrappedData((List<ScrappedSong> songs) => { }));
             StartCoroutine(WaitForSongListUI());
         }
 

+ 5 - 0
SongBrowserPlugin/SongBrowserPlugin.csproj

@@ -50,6 +50,9 @@
     <Reference Include="IllusionPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>D:\Games\Steam\SteamApps\common\Beat Saber\Beat Saber_Data\Managed\IllusionPlugin.dll</HintPath>
     </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>D:\Games\Steam\SteamApps\common\Beat Saber\Beat Saber_Data\Managed\Newtonsoft.Json.dll</HintPath>
+    </Reference>
     <Reference Include="SongLoaderPlugin, Version=5.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>D:\Games\Steam\SteamApps\common\Beat Saber\Plugins\SongLoaderPlugin.dll</HintPath>
@@ -111,6 +114,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="DataAccess\BeatSaverApi\BeatSaverApiResults.cs" />
+    <Compile Include="DataAccess\CustomHelpers.cs" />
     <Compile Include="DataAccess\FileSystem\Directory.cs" />
     <Compile Include="DataAccess\FileSystem\Folder.cs" />
     <Compile Include="DataAccess\LoadScripts.cs" />
@@ -122,6 +126,7 @@
     <Compile Include="DataAccess\PlaylistWriter.cs" />
     <Compile Include="DataAccess\ScoreSaberDatabase.cs" />
     <Compile Include="DataAccess\Network\Downloader.cs" />
+    <Compile Include="DataAccess\ScrappedData.cs" />
     <Compile Include="Logging\Logger.cs" />
     <Compile Include="PluginConfig.cs" />
     <Compile Include="UI\SceneEvents.cs" />

+ 79 - 11
SongBrowserPlugin/UI/Playlists/PlaylistFlowCoordinator.cs

@@ -7,8 +7,9 @@ using SongLoaderPlugin;
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.IO;
+using System.Diagnostics;
 using System.Linq;
+using System.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.Networking;
 using VRUI;
@@ -174,10 +175,30 @@ namespace SongBrowserPlugin.UI
 
         public IEnumerator GetInfoForSong(Playlist playlist, PlaylistSong song, Action<Song> songCallback)
         {
-            string url = $"{PluginConfig.BeatsaverURL}/api/songs/detail/{song.Key}";
-            if (!string.IsNullOrEmpty(playlist.CustomDetailUrl))
+            string url = "";
+            bool _usingHash = false;
+            if (!string.IsNullOrEmpty(song.Key))
             {
-                url = playlist.CustomDetailUrl + song.Key;
+                url = $"{PluginConfig.BeatsaverURL}/api/songs/detail/{song.Key}";
+                if (!string.IsNullOrEmpty(playlist.CustomDetailUrl))
+                {
+                    url = playlist.CustomDetailUrl + song.Key;
+                }
+            }
+            else if (!string.IsNullOrEmpty(song.Hash))
+            {
+                url = $"{PluginConfig.BeatsaverURL}/api/songs/search/hash/{song.Hash}";
+                _usingHash = true;
+            }
+            else if (!string.IsNullOrEmpty(song.LevelId))
+            {
+                string hash = CustomHelpers.CheckHex(song.LevelId.Substring(0, Math.Min(32, song.LevelId.Length)));
+                url = $"{PluginConfig.BeatsaverURL}/api/songs/search/hash/{hash}";
+                _usingHash = true;
+            }
+            else
+            {
+                yield break;
             }
 
             UnityWebRequest www = UnityWebRequest.Get(url);
@@ -193,7 +214,21 @@ namespace SongBrowserPlugin.UI
                 try
                 {
                     JSONNode node = JSON.Parse(www.downloadHandler.text);
-                    songCallback?.Invoke(new Song(node["song"]));
+
+                    if (_usingHash)
+                    {
+                        if (node["songs"].Count == 0)
+                        {
+                            Logger.Error($"Song {song.SongName} doesn't exist on BeatSaver!");
+                            songCallback?.Invoke(null);
+                            yield break;
+                        }
+                        songCallback?.Invoke(Song.FromSearchNode(node["songs"][0]));
+                    }
+                    else
+                    {
+                        songCallback?.Invoke(new Song(node["song"]));
+                    }
                 }
                 catch (Exception e)
                 {
@@ -227,15 +262,46 @@ namespace SongBrowserPlugin.UI
         public static void MatchSongsForPlaylist(Playlist playlist, bool matchAll = false)
         {
             if (!SongLoader.AreSongsLoaded || SongLoader.AreSongsLoading || playlist.Title == "All songs" || playlist.Title == "Your favorite songs") return;
+            Logger.Info("Started matching songs for playlist \"" + playlist.Title + "\"...");
             if (!playlist.Songs.All(x => x.Level != null) || matchAll)
             {
-                playlist.Songs.ForEach(x =>
+                Stopwatch execTime = new Stopwatch();
+                execTime.Start();
+                playlist.Songs.AsParallel().ForAll(x =>
                 {
                     if (x.Level == null || matchAll)
                     {
-                        x.Level = SongLoader.CustomLevels.FirstOrDefault(y => (y.customSongInfo.path.Contains(x.Key) && Directory.Exists(y.customSongInfo.path)) || (string.IsNullOrEmpty(x.LevelId) ? false : y.levelID.StartsWith(x.LevelId)));
+                        try
+                        {
+                            if (!string.IsNullOrEmpty(x.LevelId)) //check that we have levelId and if we do, try to match level
+                            {
+                                x.Level = SongLoader.CustomLevels.FirstOrDefault(y => y.levelID == x.LevelId);
+                            }
+                            if (x.Level == null && !string.IsNullOrEmpty(x.Hash)) //if level is still null, check that we have hash and if we do, try to match level
+                            {
+                                x.Level = SongLoader.CustomLevels.FirstOrDefault(y => y.levelID.StartsWith(x.Hash.ToUpper()));
+                            }
+                            if (x.Level == null && !string.IsNullOrEmpty(x.Key)) //if level is still null, check that we have key and if we do, try to match level
+                            {
+                                ScrappedSong song = ScrappedData.Songs.FirstOrDefault(z => z.Key == x.Key);
+                                if (song != null)
+                                {
+                                    x.Level = SongLoader.CustomLevels.FirstOrDefault(y => y.levelID.StartsWith(song.Hash));
+                                }
+                                else
+                                {
+                                    x.Level = SongLoader.CustomLevels.FirstOrDefault(y => y.customSongInfo.path.Contains(x.Key));
+                                }
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            Logger.Warning($"Unable to match song with {(string.IsNullOrEmpty(x.Key) ? " unknown key!" : ("key " + x.Key + " !"))} Exception: {e}");
+                        }
                     }
                 });
+                Logger.Info($"Matched all songs for playlist \"{playlist.Title}\"! Time: {execTime.Elapsed.TotalSeconds.ToString("0.00")}s");
+                execTime.Reset();
             }
         }
 
@@ -246,11 +312,13 @@ namespace SongBrowserPlugin.UI
         public void MatchSongsForAllPlaylists(bool matchAll = false)
         {
             Logger.Info("Matching songs for all playlists!");
-            foreach (Playlist playlist in _playlistsReader.Playlists)
+            Task.Run(() =>
             {
-                MatchSongsForPlaylist(playlist, matchAll);
-            }
-            Logger.Info("Done matching songs for all playlists...");
+                for (int i = 0; i < _playlistsReader.Playlists.Count; i++)
+                {
+                    MatchSongsForPlaylist(_playlistsReader.Playlists[i], matchAll);
+                }
+            });
         }
 
 #if DEBUG