private static async void ProcessSongRequest(int index, bool fromHistory = false) { if ((RequestQueue.Songs.Count > 0 && !fromHistory) || (RequestHistory.Songs.Count > 0 && fromHistory)) { SongRequest request = null; if (!fromHistory) { SetRequestStatus(index, RequestStatus.Played); request = DequeueRequest(index); } else { request = RequestHistory.Songs.ElementAt(index); } if (request == null) { Plugin.Log("Can't process a null request! Aborting!"); return; } else { Plugin.Log($"Processing song request {request.song["songName"].Value}"); } string songName = request.song["songName"].Value; string songIndex = $"{request.song["id"].Value} ({request.song["songName"].Value} - {request.song["levelAuthor"].Value})"; songIndex = normalize.RemoveDirectorySymbols(ref songIndex); // Remove invalid characters. string currentSongDirectory = Path.Combine(Environment.CurrentDirectory, "Beat Saber_Data\\CustomLevels", songIndex); string songHash = request.song["hash"].Value.ToUpper(); // Check to see if level exists, download if not. // Replace with level check. //CustomLevel[] levels = SongLoader.CustomLevels.Where(l => l.levelID.StartsWith(songHash)).ToArray(); //if (levels.Length == 0) var rat = SongCore.Collections.levelIDsForHash(songHash); bool mapexists = (rat.Count > 0) && (rat[0] != ""); if (!SongCore.Loader.CustomLevels.ContainsKey(currentSongDirectory) && !mapexists) { Utilities.EmptyDirectory(".requestcache", false); //SongMap map; //if (MapDatabase.MapLibrary.TryGetValue(songIndex, out map)) //{ // if (map.path != "") // { // songIndex = map.song["version"].Value; // songName = map.song["songName"].Value; // currentSongDirectory = Path.Combine(Environment.CurrentDirectory, "CustomSongs", songIndex); // songHash = map.song["hashMd5"].Value.ToUpper(); // Directory.CreateDirectory(currentSongDirectory); // // HACK to allow playing alternate songs not in custom song directory // CopyFilesRecursively(new DirectoryInfo(map.path),new DirectoryInfo( currentSongDirectory)); // goto here; // } //} //Plugin.Log("Downloading"); if (Directory.Exists(currentSongDirectory)) { Utilities.EmptyDirectory(currentSongDirectory, true); Plugin.Log($"Deleting {currentSongDirectory}"); } string localPath = Path.Combine(Environment.CurrentDirectory, ".requestcache", $"{request.song["id"].Value}.zip"); //string dl = $"https://beatsaver.com {request.song["downloadURL"].Value}"; //Instance.QueueChatMessage($"Download url: {dl}, {request.song}"); // Insert code to replace local path with ZIP path here //SongMap map; //if (MapDatabase.MapLibrary.TryGetValue(songIndex, out map)) //{ // if (map.path != "") // { // songIndex = map.song["version"].Value; // songName = map.song["songName"].Value; // currentSongDirectory = Path.Combine(Environment.CurrentDirectory, "CustomSongs", songIndex); // songHash = map.song["hashMd5"].Value.ToUpper(); // Directory.CreateDirectory(currentSongDirectory); // // HACK to allow playing alternate songs not in custom song directory // CopyFilesRecursively(new DirectoryInfo(map.path),new DirectoryInfo( currentSongDirectory)); // goto here; // } //} #if UNRELEASED // Direct download hack var ext = Path.GetExtension(request.song["coverURL"].Value); var k = request.song["coverURL"].Value.Replace(ext, ".zip"); var songZip = await Plugin.WebClient.DownloadSong($"https://beatsaver.com{k}", System.Threading.CancellationToken.None); #else var songZip = await Plugin.WebClient.DownloadSong($"https://beatsaver.com{request.song["downloadURL"].Value}", System.Threading.CancellationToken.None); #endif Stream zipStream = new MemoryStream(songZip); try { // open zip archive from memory stream ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read); archive.ExtractToDirectory(currentSongDirectory); archive.Dispose(); } catch (Exception e) { Plugin.Log($"Unable to extract ZIP! Exception: {e}"); return; } zipStream.Close(); here: await Task.Run(async() => { while (!SongCore.Loader.AreSongsLoaded && SongCore.Loader.AreSongsLoading) { await Task.Delay(25); } }); Loader.Instance.RefreshSongs(); await Task.Run(async() => { while (!SongCore.Loader.AreSongsLoaded && SongCore.Loader.AreSongsLoading) { await Task.Delay(25); } }); Utilities.EmptyDirectory(".requestcache", true); //levels = SongLoader.CustomLevels.Where(l => l.levelID.StartsWith(songHash)).ToArray(); } else { //Instance.QueueChatMessage($"Directory exists: {currentSongDirectory}"); Plugin.Log($"Song {songName} already exists!"); } // Dismiss the song request viewcontroller now //_songRequestMenu.Dismiss(); _flowCoordinator.Dismiss(); if (true) { //Plugin.Log($"Scrolling to level {levels[0].levelID}"); bool success = false; Dispatcher.RunCoroutine(SongListUtils.ScrollToLevel(request.song["hash"].Value.ToUpper(), (s) => success = s, false)); // Redownload the song if we failed to scroll to it } else { Plugin.Log("Failed to find new level!"); } if (!request.song.IsNull && RequestBotConfig.Instance.SendNextSongBeingPlayedtoChat) { new DynamicText().AddUser(ref request.requestor).AddSong(request.song).QueueMessage(NextSonglink.ToString()); // Display next song message } #if UNRELEASED if (!request.song.IsNull) // Experimental! { TwitchWebSocketClient.SendCommand("/marker " + new DynamicText().AddUser(ref request.requestor).AddSong(request.song).Parse(NextSonglink.ToString())); } #endif } }
private void Awake() { DontDestroyOnLoad(gameObject); Instance = this; #if UNRELEASED var startingmem = GC.GetTotalMemory(true); //var folder = Path.Combine(Environment.CurrentDirectory, "userdata","streamcore"); //List<FileInfo> files = new List<FileInfo>(); // List that will hold the files and subfiles in path //List<DirectoryInfo> folders = new List<DirectoryInfo>(); // List that hold direcotries that cannot be accessed //DirectoryInfo di = new DirectoryInfo(folder); //Dictionary<string, string> remap = new Dictionary<string, string>(); //foreach (var entry in listcollection.OpenList("all.list").list) // { // //Instance.QueueChatMessage($"Map {entry}"); // string[] remapparts = entry.Split('-'); // if (remapparts.Length == 2) // { // int o; // if (Int32.TryParse(remapparts[1], out o)) // { // try // { // remap.Add(remapparts[0], o.ToString("x")); // } // catch // { } // //Instance.QueueChatMessage($"Map {remapparts[0]} : {o.ToString("x")}"); // } // } //} //Instance.QueueChatMessage($"Scanning lists"); //FullDirList(di, "*.deck"); //void FullDirList(DirectoryInfo dir, string searchPattern) //{ // try // { // foreach (FileInfo f in dir.GetFiles(searchPattern)) // { // var List = listcollection.OpenList(f.Name).list; // for (int i=0;i<List.Count;i++) // { // if (remap.ContainsKey(List[i])) // { // //Instance.QueueChatMessage($"{List[i]} : {remap[List[i]]}"); // List[i] = remap[List[i]]; // } // } // listcollection.OpenList(f.Name).Writefile(f.Name); // } // } // catch // { // Console.WriteLine("Directory {0} \n could not be accessed!!!!", dir.FullName); // return; // } //} //NOTJSON.UNITTEST(); #endif playedfilename = Path.Combine(Plugin.DataPath, "played.dat"); // Record of all the songs played in the current session try { string filesToDelete = Path.Combine(Environment.CurrentDirectory, "FilesToDelete"); if (Directory.Exists(filesToDelete)) { Utilities.EmptyDirectory(filesToDelete); } try { DateTime LastBackup; if (!DateTime.TryParse(RequestBotConfig.Instance.LastBackup, out LastBackup)) { LastBackup = DateTime.MinValue; } TimeSpan TimeSinceBackup = DateTime.Now - LastBackup; if (TimeSinceBackup > TimeSpan.FromHours(RequestBotConfig.Instance.SessionResetAfterXHours)) { Backup(); } } catch (Exception ex) { Plugin.Log(ex.ToString()); Instance.QueueChatMessage("Failed to run Backup"); } try { TimeSpan PlayedAge = GetFileAgeDifference(playedfilename); if (PlayedAge < TimeSpan.FromHours(RequestBotConfig.Instance.SessionResetAfterXHours)) { played = ReadJSON(playedfilename); // Read the songsplayed file if less than x hours have passed } } catch (Exception ex) { Plugin.Log(ex.ToString()); Instance.QueueChatMessage("Failed to clear played file"); } if (RequestBotConfig.Instance.PPSearch) { GetPPData(); // Start loading PP data } MapDatabase.LoadDatabase(); if (RequestBotConfig.Instance.LocalSearch) { MapDatabase.LoadCustomSongs(); // This is a background process } RequestQueue.Read(); // Might added the timespan check for this too. To be decided later. RequestHistory.Read(); listcollection.OpenList("banlist.unique"); #if UNRELEASED //GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; //GC.Collect(); //Instance.QueueChatMessage($"hashentries: {SongMap.hashcount} memory: {(GC.GetTotalMemory(false) - startingmem) / 1048576} MB"); #endif listcollection.ClearOldList("duplicate.list", TimeSpan.FromHours(RequestBotConfig.Instance.SessionResetAfterXHours)); UpdateRequestUI(); InitializeCommands(); //EnhancedStreamChat.ChatHandler.ChatMessageFilters += MyChatMessageHandler; // TODO: Reimplement this filter maybe? Or maybe we put it directly into EnhancedStreamChat COMMAND.CommandConfiguration(); RunStartupScripts(); ProcessRequestQueue(); TwitchMessageHandlers.PRIVMSG += PRIVMSG; RequestBotConfig.Instance.ConfigChangedEvent += OnConfigChangedEvent; IsPluginReady = true; } catch (Exception ex) { Plugin.Log(ex.ToString()); Instance.QueueChatMessage(ex.ToString()); } }