private static SongFields ReadWelcomeMessage(string host, int port) { var stopwatch = new Stopwatch(); var message = new StringBuilder(); var buffer = new byte[4096]; Logger.log.Debug($"Connecting with TCP to {host}:{port}"); stopwatch.Start(); try { using (var client = new TcpClient(host, port)) using (var stream = client.GetStream()) { Logger.log.Debug($"TCP connected in {stopwatch.Elapsed}"); var username = Encoding.UTF8.GetBytes("BeatSaber refresh"); stream.Write(username, 0, username.Length); Logger.log.Debug("Sent username"); // Receive until difficulty contents field (index 3) is received, separated by ";;;": // 0: folder name::difficulty index // 1: contents of info.json // 2: path to relevant difficulty.json // 3: contents of difficulty.json // 4: audio filename // 5: audio file size // 6: audio download url Logger.log.Debug("Reading welcome message"); stopwatch.Restart(); while (Regex.Matches(message.ToString(), ";;;").Count < 4) { var bytesRead = stream.Read(buffer, 0, buffer.Length); message.Append(Encoding.UTF8.GetChars(new ArraySegment <byte>(buffer, 0, bytesRead).ToArray())); } } } catch (SocketException e) { throw new Exception($"Failed to connect to {host}:{port}: {e.Message}", e); } catch (IOException e) { throw new Exception($"Networking error: {e.Message}", e); } Logger.log.Debug($"Read welcome message in {stopwatch.Elapsed} seconds"); var components = message.ToString().Split(new[] { ";;;" }, StringSplitOptions.None); var fields = new SongFields { FolderName = components[0].Split(new[] { "::" }, StringSplitOptions.None)[0], DifficultyFilename = components[2], DifficultyContent = components[3], }; Logger.log.Debug($"Difficulty size: {fields.DifficultyContent.Length} characters"); return(fields); }
private static void ConvertSong(SongFields fields) { var customSongsPath = $"{BeatSaber.InstallPath}\\Beat Saber_Data\\CustomWIPLevels"; var songPath = $"{customSongsPath}\\{fields.FolderName}"; var difficultyPath = $"{songPath}\\{fields.DifficultyFilename}"; Logger.log.Debug($"Writing to {difficultyPath}"); using (var outputDifficulty = File.CreateText(difficultyPath)) { outputDifficulty.Write(fields.DifficultyContent); } Logger.log.Debug("Wrote file"); // Checking the exit code of the process isn't helpful here because once the arguments are // validated, songe-converter exits 0 regardless of whether it converted a song. var process = new Process(); var startInfo = new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Normal, FileName = $"{BeatSaber.InstallPath}\\songe-converter.exe", Arguments = $"-k -a \"{customSongsPath}\"", UseShellExecute = false, }; process.StartInfo = startInfo; process.EnableRaisingEvents = true; Logger.log.Debug("Starting conversion."); var stopwatch = new Stopwatch(); stopwatch.Start(); try { process.Start(); } catch (Win32Exception e) { throw new Exception($"Failed to run songe-converter at\n{process.StartInfo.FileName}\n{new Win32Exception(e.NativeErrorCode).Message}", e); } process.WaitForExit(); Logger.log.Debug($"Conversion complete in {stopwatch.Elapsed}; refreshing songs."); }
/// <summary> /// Creates a new SongForm /// </summary> /// <param name="pc">The project controller</param> /// <param name="user">The user that was logged in</param> public SongForm(IController pc, User user) { // Initialize the class this.currentUser = user; this.projectController = pc; InitializeComponent(); // Set up event handlers for sorting the table and pressing enter in the search text box dataGridView1.ColumnHeaderMouseClick += new DataGridViewCellMouseEventHandler(this.columnHeaders_Click); searchBox.KeyPress += new KeyPressEventHandler(onKeyPress); this.MinimumSize = this.Size; this.MaximumSize = this.Size; // If not logged in as an owner, disable some functionality if (!user.IsOwner) { // Disable the ability to add/delete songs and save/backup the database for a regular user databaseToolStripMenuItem.Visible = false; songLibraryToolStripMenuItem.Visible = false; deleteButton.Visible = false; deleteButton.Enabled = false; // Don't allow regular user to edit fields foreach (DataGridViewColumn d in dataGridView1.Columns) { d.ReadOnly = true; } } else { // Set up event handlers for editing fields dataGridView1.CellBeginEdit += new DataGridViewCellCancelEventHandler(dataGridView1_CellBeginEdit); dataGridView1.CellEndEdit += new DataGridViewCellEventHandler(dataGridView1_CellEndEdit); // Register delete key press while focus is on the table dataGridView1.KeyDown += new KeyEventHandler(dataGridView1_KeyDown); } // Set the default sorting for the table currentSortField = SongFields.Artist; currentSortType = SortType.Ascending; currentSearchString = null; currentSearchField = SongFields.Artist; // Set the search field drop down box to Artist fieldSelectBox.SelectedIndex = 0; // Load the database loadDatabase(); }
/// <summary> /// Searches the database in the specified field for the specified text /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void searchButton_Click(object sender, EventArgs e) { // Get information and search for it currentSearchString = searchBox.Text.Trim(); currentSearchField = (SongFields)fieldSelectBox.SelectedIndex; currentSortField = SongFields.Artist; currentSortType = SortType.Ascending; dataGridView1.DataSource = projectController.GetSortedSearchResults(searchBox.Text.Trim(), (SongFields)fieldSelectBox.SelectedIndex, currentSortField, currentSortType); }
/// <summary> /// Resets the sorting or searching /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void resetButton_Click(object sender, EventArgs e) { // Restore the defaults currentSortField = SongFields.Artist; currentSortType = SortType.Ascending; currentSearchString = null; searchBox.Text = ""; fieldSelectBox.SelectedIndex = 0; dataGridView1.DataSource = projectController.GetSortedSongList(currentSortField, currentSortType); }
/// <summary> /// Sorts the list of songs when the column headers are clicked on /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void columnHeaders_Click(object sender, DataGridViewCellMouseEventArgs e) { if (e.ColumnIndex > 3) { return; } // Only change from ascending to descending or vice versa if the sort field isn't changing else if (currentSortField == this.headerFields[e.ColumnIndex]) { currentSortType = currentSortType == SortType.Ascending ? SortType.Descending : SortType.Ascending; } // Default to ascending when switching to a different sort field else { currentSortType = SortType.Ascending; } // Set the new sort field and refresh the table to match the new sort settings currentSortField = this.headerFields[e.ColumnIndex]; if (this.currentSearchString != null) { dataGridView1.DataSource = projectController.GetSortedSearchResults(this.currentSearchString, this.currentSearchField, this.currentSortField, this.currentSortType); } else { dataGridView1.DataSource = projectController.GetSortedSongList(currentSortField, currentSortType); } }
/// <summary> /// Gets a list of songs in the database, searches them, and then sorts them /// </summary> /// <param name="searchString">The string to search for</param> /// <param name="searchField">The song field to search in</param> /// <param name="sortField">The song field to sort by</param> /// <param name="sortType">The sorting type</param> /// <returns>A searched and sorted list of songs</returns> public Song[] GetSortedSearchResults(string searchString, SongFields searchField, SongFields sortField, SortType sortType) { Song[] songs = dataAccess.GetAllSongs(); songs = this.SearchSongs(songs, searchString, searchField); songs = this.SortSongs(songs, sortField, sortType); return songs; }
/// <summary> /// Sorts an array of songs /// </summary> /// <param name="songsToSort">The songs to sort</param> /// <param name="field">The song field to sort by</param> /// <param name="sortType">The type of sort to perform</param> /// <returns>The sorted list of songs</returns> private Song[] SortSongs(Song[] songsToSort, SongFields field, SortType sortType) { switch (field) { case SongFields.Album: if (sortType == SortType.Ascending) { songsToSort = songsToSort.OrderBy(s => s.Album).ThenBy(a => a.Title).ToArray(); } else { songsToSort = songsToSort.OrderByDescending(s => s.Album).ThenByDescending(a => a.Title).ToArray(); } break; case SongFields.Artist: if (sortType == SortType.Ascending) { songsToSort = songsToSort.OrderBy(s => s.Artist).ThenBy(a => a.Album).ThenBy(a => a.Title).ToArray(); } else { songsToSort = songsToSort.OrderByDescending(s => s.Artist).ThenByDescending(a => a.Album).ThenByDescending(a => a.Title).ToArray(); } break; case SongFields.Genre: if (sortType == SortType.Ascending) { songsToSort = songsToSort.OrderBy(s => s.Genre).ThenBy(a => a.Artist).ThenBy(a => a.Album).ThenBy(a => a.Title).ToArray(); } else { songsToSort = songsToSort.OrderByDescending(s => s.Genre).ThenBy(a => a.Artist).ThenByDescending(a => a.Album).ThenByDescending(a => a.Title).ToArray(); } break; case SongFields.Title: if (sortType == SortType.Ascending) { songsToSort = songsToSort.OrderBy(s => s.Title).ThenBy(a => a.Artist).ToArray(); } else { songsToSort = songsToSort.OrderByDescending(s => s.Title).ThenByDescending(a => a.Artist).ToArray(); } break; } return songsToSort; }
/// <summary> /// Searches an array of songs /// </summary> /// <param name="songsToSearch">The songs to search</param> /// <param name="searchString">The string to searh for</param> /// <param name="searchField">The song field to search in</param> /// <returns>The search results</returns> private Song[] SearchSongs(Song[] songsToSearch, string searchString, SongFields searchField) { switch (searchField) { case SongFields.Album: songsToSearch = songsToSearch.Where(s => s.Album.ToUpper().Contains(searchString.ToUpper())).ToArray(); break; case SongFields.Artist: songsToSearch = songsToSearch.Where(s => s.Artist.ToUpper().Contains(searchString.ToUpper())).ToArray(); break; case SongFields.Genre: songsToSearch = songsToSearch.Where(s => s.Genre.ToUpper().Contains(searchString.ToUpper())).ToArray(); break; case SongFields.Title: songsToSearch = songsToSearch.Where(s => s.Title.ToUpper().Contains(searchString.ToUpper())).ToArray(); break; } return songsToSearch; }
/// <summary> /// Gets a list of songs in the database sorted based on the column header clicked and the previous type of sorting (ascending or descending) /// </summary> /// <param name="field">The field to sort the songs by</param> /// <param name="sortType">The type of sort to perform, ascending or descending</param> /// <returns>A list of the sorted songs</returns> public Song[] GetSortedSongList(SongFields field, SortType sortType) { Song[] songs = dataAccess.GetAllSongs(); return this.SortSongs(songs, field, sortType); }
/// <summary> /// Initializes a new instance of the <see cref="Song" /> class. /// </summary> public Song() : base(CLASS_NAME) { mFields = new SongFields(this); }
protected async Task<IMediaItemList<Song>> GetSongs(string filterName, int id, SongFields fields, int? startIndex, int? endIndex, SortMethods? sortMethod, Orders? order) { List<JsonParam> parameters = new List<JsonParam>(); parameters.Add(new JsonParamObject("filter", new JsonParam(filterName, id))); parameters.AddRange(ClientUtils.GetLimitsParameter(startIndex, endIndex)); parameters.AddRange(ClientUtils.GetSortOrderParameter(sortMethod, order)); parameters.Add(new JsonParam("properties", fields ?? DefaultSongProperties)); return await _client.PostAsync("AudioLibrary.GetSongs", _serializer.Parse<XbmcItemList<Song>>, parameters.ToArray()); }
/// <summary> /// Retrieve all songs from specified artist /// </summary> public async Task<IMediaItemList<Song>> GetSongsForGenre(int genreId, SongFields fields, int? startIndex, int? endIndex, SortMethods? sortMethod, Orders? order) { return await GetSongs("genreid", genreId, fields, startIndex, endIndex, sortMethod, order); }
/// <summary> /// Retrieve all songs from specified artist /// </summary> public async Task<IMediaItemList<Song>> GetSongsForAlbum(int albumId, SongFields fields, int? startIndex, int? endIndex, SortMethods? sortMethod, Orders? order) { return await GetSongs("albumid", albumId, fields, startIndex, endIndex, sortMethod, order); }
/// <summary> /// Retrieve details about a specific song /// </summary> public async Task<Song> GetSong(int songId, SongFields fields) { return await _client.PostAsync("AudioLibrary.GetSongDetails", t => _serializer.Parse<Song>(t, "songdetails"), new JsonParam("songid", songId), new JsonParam("properties", fields ?? DefaultSongProperties)); }