public static void DequeueRequest(SongRequest request, bool updateUI = true) { if (request.status != RequestStatus.Wrongsong && request.status != RequestStatus.SongSearch) { RequestHistory.Songs.Insert(0, request); // Wrong song requests are not logged into history, is it possible that other status states shouldn't be moved either? } if (RequestHistory.Songs.Count > RequestBotConfig.Instance.RequestHistoryLimit) { int diff = RequestHistory.Songs.Count - RequestBotConfig.Instance.RequestHistoryLimit; RequestHistory.Songs.RemoveRange(RequestHistory.Songs.Count - diff - 1, diff); } RequestQueue.Songs.Remove(request); RequestHistory.Write(); RequestQueue.Write(); // Decrement the requestors request count, since their request is now out of the queue if (!RequestBotConfig.Instance.LimitUserRequestsToSession) { if (RequestTracker.ContainsKey(request.requestor.Id)) { RequestTracker[request.requestor.Id].numRequests--; } } if (updateUI == false) { return; } UpdateRequestUI(); _refreshQueue = true; }
// BUG: Testing major changes. This will get seriously refactored soon. private async Task CheckRequest(RequestInfo requestInfo) { TwitchUser requestor = requestInfo.requestor; string request = requestInfo.request; string normalrequest = normalize.NormalizeBeatSaverString(requestInfo.request); var id = GetBeatSaverId(normalize.RemoveSymbols(ref request, normalize._SymbolsNoDash)); if (id != "") { // Remap song id if entry present. This is one time, and not correct as a result. No recursion right now, could be confusing to the end user. if (songremap.ContainsKey(id) && !requestInfo.flags.HasFlag(CmdFlags.NoFilter)) { request = songremap[id]; QueueChatMessage($"Remapping request {requestInfo.request} to {request}"); } string requestcheckmessage = IsRequestInQueue(normalize.RemoveSymbols(ref request, normalize._SymbolsNoDash)); // Check if requested ID is in Queue if (requestcheckmessage != "") { QueueChatMessage(requestcheckmessage); return; } if (RequestBotConfig.Instance.OfflineMode && RequestBotConfig.Instance.offlinepath != "" && !MapDatabase.MapLibrary.ContainsKey(id)) { foreach (string directory in Directory.GetDirectories(RequestBotConfig.Instance.offlinepath, id + "*")) { await MapDatabase.LoadCustomSongs(directory, id); await Task.Run(async() => { while (MapDatabase.DatabaseLoading) { await Task.Delay(25); } }); break; } } } JSONNode result = null; string errorMessage = ""; // Get song query results from beatsaver.com if (!RequestBotConfig.Instance.OfflineMode) { string requestUrl = (id != "") ? $"https://beatsaver.com/api/maps/detail/{normalize.RemoveSymbols(ref request, normalize._SymbolsNoDash)}" : $"https://beatsaver.com/api/search/text/0?q={normalrequest}"; var resp = await Plugin.WebClient.GetAsync(requestUrl, System.Threading.CancellationToken.None); if (resp.IsSuccessStatusCode) { result = resp.ConvertToJsonNode(); } else { errorMessage = $"Invalid BeatSaver ID \"{request}\" specified. {requestUrl}"; } } SongFilter filter = SongFilter.All; if (requestInfo.flags.HasFlag(CmdFlags.NoFilter)) { filter = SongFilter.Queue; } List <JSONObject> songs = GetSongListFromResults(result, request, ref errorMessage, filter, requestInfo.state.sort != "" ? requestInfo.state.sort : AddSortOrder.ToString()); bool autopick = RequestBotConfig.Instance.AutopickFirstSong || requestInfo.flags.HasFlag(CmdFlags.Autopick); // Filter out too many or too few results if (songs.Count == 0) { if (errorMessage == "") { errorMessage = $"No results found for request \"{request}\""; } } else if (!autopick && songs.Count >= 4) { errorMessage = $"Request for '{request}' produces {songs.Count} results, narrow your search by adding a mapper name, or use https://beatsaver.com to look it up."; } else if (!autopick && songs.Count > 1 && songs.Count < 4) { var msg = new QueueLongMessage(1, 5); msg.Header($"@{requestor.DisplayName}, please choose: "); foreach (var eachsong in songs) { msg.Add(new DynamicText().AddSong(eachsong).Parse(BsrSongDetail), ", "); } msg.end("...", $"No matching songs for for {request}"); return; } else { if (!requestInfo.flags.HasFlag(CmdFlags.NoFilter)) { errorMessage = SongSearchFilter(songs[0], false); } } // Display reason why chosen song was rejected, if filter is triggered. Do not add filtered songs if (errorMessage != "") { QueueChatMessage(errorMessage); return; } JSONObject song = songs[0]; // Song requests should try to be current. If the song was local, we double check for a newer version //if ((song["downloadUrl"].Value == "") && !RequestBotConfig.Instance.OfflineMode ) //{ // //QueueChatMessage($"song: {song["id"].Value.ToString()} ,{song["songName"].Value}"); // yield return Utilities.Download($"https://beatsaver.com/api/maps/detail/{song["id"].Value.ToString()}", Utilities.DownloadType.Raw, null, // // Download success // (web) => // { // result = JSON.Parse(web.downloadHandler.text); // var newsong = result["song"].AsObject; // if (result != null && newsong["version"].Value != "") // { // new SongMap(newsong); // song = newsong; // } // }, // // Download failed, song probably doesn't exist on beatsaver // (web) => // { // // Let player know that the song is not current on BeatSaver // requestInfo.requestInfo += " *LOCAL ONLY*"; // ; //errorMessage = $"Invalid BeatSaver ID \"{request}\" specified. {requestUrl}"; // }); //} RequestTracker[requestor.Id].numRequests++; listcollection.add(duplicatelist, song["id"].Value); if ((requestInfo.flags.HasFlag(CmdFlags.MoveToTop))) { RequestQueue.Songs.Insert(0, new SongRequest(song, requestor, requestInfo.requestTime, RequestStatus.Queued, requestInfo.requestInfo)); } else { RequestQueue.Songs.Add(new SongRequest(song, requestor, requestInfo.requestTime, RequestStatus.Queued, requestInfo.requestInfo)); } RequestQueue.Write(); Writedeck(requestor, "savedqueue"); // This can be used as a backup if persistent Queue is turned off. if (!requestInfo.flags.HasFlag(CmdFlags.SilentResult)) { new DynamicText().AddSong(ref song).QueueMessage(AddSongToQueueText.ToString()); } Dispatcher.RunOnMainThread(() => { UpdateRequestUI(); _refreshQueue = true; }); }
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)) { 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(); RequestBotConfig.Instance.ConfigChangedEvent += OnConfigChangedEvent; } catch (Exception ex) { Plugin.Log(ex.ToString()); Instance.QueueChatMessage(ex.ToString()); } }