public override IEnumerable <Issue> GetIssues(BeatmapSet aBeatmapSet) { foreach (Beatmap beatmap in aBeatmapSet.beatmaps) { if (beatmap.generalSettings.mode == Beatmap.Mode.Taiko) { Common.CalculateTaikoSR(beatmap); yield return(new Issue(GetTemplate("Recalculated Star Rating"), beatmap, beatmap.ToString(), beatmap.starRating)); } } }
private static IEnumerable <TagFile> GetTagFiles(BeatmapSet beatmapSet, List <string> fileNames) { if (beatmapSet.songPath == null) { yield break; } foreach (string fileName in fileNames) { TagLib.File file = null; string errorTemplate = ""; List <object> arguments = new List <object> { fileName }; if (fileName.StartsWith("..")) { errorTemplate = "Leaves Folder"; } else { string[] files; try { files = Directory.GetFiles(beatmapSet.songPath, fileName + (fileName.Contains(".") ? "" : ".*")); } catch (DirectoryNotFoundException) { files = new string[] { }; } if (files.Length > 0) { try { file = new FileAbstraction(files[0]).GetTagFile(); } catch (Exception exception) { errorTemplate = "Exception"; arguments.Add(ExceptionTag(exception)); } } else { errorTemplate = "Missing"; } } yield return(new TagFile(file, errorTemplate, arguments.ToArray())); } }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { var modeVideoPairs = new List <ModeVideoPair>(); var modes = beatmapSet.beatmaps.Select(beatmap => beatmap.generalSettings.mode).Distinct(); foreach (Beatmap.Mode mode in modes) { List <string> videoNames = beatmapSet.beatmaps .Where(beatmap => beatmap.generalSettings.mode == mode) .Select(beatmap => beatmap.videos.FirstOrDefault()?.path ?? "None") .Distinct() .ToList(); // It's possible the .osb file includes a video as well, which would run at the // same time as *any* .osu video file (either in front of or behind the other). string osbVideoPath = beatmapSet.osb?.videos.FirstOrDefault()?.path; if (osbVideoPath != null && !videoNames.Contains(osbVideoPath)) { videoNames.Add(osbVideoPath); } foreach (string videoName in videoNames) { var suchBeatmaps = beatmapSet.beatmaps .Where(beatmap => (beatmap.videos.FirstOrDefault()?.path ?? "None") == videoName || beatmapSet.osb?.videos.FirstOrDefault()?.path == videoName) .ToList(); if (videoNames.Count > 1 && suchBeatmaps.Any()) { yield return(new Issue(GetTemplate("Same Mode"), null, videoName, string.Join(", ", suchBeatmaps))); } if (!modeVideoPairs.Any(pair => pair.mode == mode && pair.videoName == videoName)) { modeVideoPairs.Add(new ModeVideoPair(mode, videoName)); } } } foreach (Issue issue in GetCrossModeIssues(modeVideoPairs)) { yield return(issue); } }
/// <summary> /// Prepares a download object for a set from bloodcat /// </summary> public static async Task <BeatmapDownload> PrepareDownloadSet(BeatmapSet set) { BeatmapDownload download; Uri downloadUri; await CheckCaptcha(set); downloadUri = new Uri("http://bloodcat.com/osu/s/" + set.Id); download = new BeatmapDownload(set, downloadUri, Cookies); return(download); }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { beatmapSet.beatmaps.ForEach(beatmap => { var calculatedBeatmap = BeatmapDistanceCalculator.Calculate(beatmap); var beatmapIdentifier = BeatmapUtil.GetBeatmapIdentifier(beatmap); CatchBeatmaps.TryRemove(beatmapIdentifier, out _); CatchBeatmaps.TryAdd(beatmapIdentifier, calculatedBeatmap); }); yield break; }
public MapsetTab(string path) { setPath = path; set = new BeatmapSet(path); var map = set.beatmaps.Find(bmap => bmap.metadataSettings.beatmapId > 0 && bmap.metadataSettings.beatmapSetId > 0); setId = (ulong)map.metadataSettings.beatmapSetId; #region setting up controls panel = new TableLayoutPanel(); panel.Dock = DockStyle.Fill; diffList = new ListBox(); diffList.Dock = DockStyle.Left; diffList.Items.Add("General"); diffList.SelectedIndexChanged += changeSelectedDifficulty; foreach (var diff in set.beatmaps) { diffList.Items.Add($"[{diff.metadataSettings.version}]"); } panel.Controls.Add(diffList, 0, 1); toolbar = new ToolStrip(); openMapsetInExplorerBtn = new ToolStripButton(); openMapsetInExplorerBtn.Text = "Open in Explorer"; openMapsetInExplorerBtn.DisplayStyle = ToolStripItemDisplayStyle.Text; openMapsetInExplorerBtn.Click += openMapsetInExplorer; toolbar.Items.Add(openMapsetInExplorerBtn); openMapsetInBrowserBtn = new ToolStripButton(); openMapsetInBrowserBtn.Text = "Open in Browser"; openMapsetInBrowserBtn.DisplayStyle = ToolStripItemDisplayStyle.Text; openMapsetInBrowserBtn.Enabled = setId > 0; openMapsetInBrowserBtn.Click += openMapsetInBrowser; toolbar.Items.Add(openMapsetInBrowserBtn); panel.Controls.Add(toolbar, 0, 0); panel.SetColumnSpan(toolbar, 2); tb = new RichTextBox(); tb.Text = "loading..."; tb.Multiline = true; tb.LinkClicked += handleOpenLink; tb.Dock = DockStyle.Fill; panel.Controls.Add(tb, 1, 1); Controls.Add(panel); #endregion // start running checks _ = Task.Run(runChecks); }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { // Checks .osu-specific storyboard elements. foreach (Beatmap beatmap in beatmapSet.beatmaps) { foreach (Sprite sprite in beatmap.sprites) { if (sprite.layer == Sprite.Layer.Overlay) { yield return(new Issue(GetTemplate("Warning"), beatmap, sprite.path, ".osu")); } } } foreach (Beatmap beatmap in beatmapSet.beatmaps) { foreach (Animation animation in beatmap.animations) { if (animation.layer == Sprite.Layer.Overlay) { yield return(new Issue(GetTemplate("Warning"), beatmap, animation.path, ".osu")); } } } // Checks .osb storyboard elements. if (beatmapSet.osb == null) { yield break; } foreach (Sprite sprite in beatmapSet.osb.sprites) { if (sprite.layer == Sprite.Layer.Overlay) { yield return(new Issue(GetTemplate("Warning"), null, sprite.path, ".osb")); } } foreach (Animation animation in beatmapSet.osb.animations) { if (animation.layer == Sprite.Layer.Overlay) { yield return(new Issue(GetTemplate("Warning"), null, animation.path, ".osb")); } } }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { Beatmap beatmap = beatmapSet.beatmaps[0]; foreach (Issue issue in GetMarkerFormatIssues(beatmap)) { yield return(issue); } foreach (Issue issue in GetNightcoreIssues(beatmap)) { yield return(issue); } }
private static void InitSnapshotDates(BeatmapSet aBeatmapSet) { snapshotDates = aBeatmapSet.beatmaps.SelectMany(aBeatmap => Snapshotter.GetSnapshots(aBeatmap) .Select(aSnapshot => aSnapshot.creationTime)) .ToList(); snapshotDates.AddRange(Snapshotter.GetSnapshots( aBeatmapSet.beatmaps.First().metadataSettings.beatmapSetId.ToString(), "files") .Select(aSnapshot => aSnapshot.creationTime)); snapshotDates = snapshotDates.Distinct().OrderBy(aDate => aDate).ToList(); }
public override IEnumerable <Issue> GetIssues(BeatmapSet aBeatmapSet) { for (int i = 0; i < aBeatmapSet.songFilePaths.Count; ++i) { string filePath = aBeatmapSet.songFilePaths[i].Substring(aBeatmapSet.songPath.Length + 1); string fileName = filePath.Split(new char[] { '/', '\\' }).Last().ToLower(); if (!aBeatmapSet.IsFileUsed(filePath) && fileName != "thumbs.db") { yield return(new Issue(GetTemplate("Unused"), null, filePath)); } } }
private static string RenderTop(BeatmapSet aBeatmapSet) { return (Div("overview-timeline-difficulties", String.Concat( aBeatmapSet.beatmaps.Select(aBeatmap => { return Div("overview-timeline-difficulty noselect", aBeatmap.metadataSettings.version ); })) )); }
private static double GetEndTime(BeatmapSet aBeatmapSet) { double endTimeObjects = aBeatmapSet.beatmaps.Max(aBeatmap => aBeatmap.hitObjects.LastOrDefault()?.GetEndTime() ?? 0); double endTimeLines = aBeatmapSet.beatmaps.Max(aBeatmap => aBeatmap.timingLines.LastOrDefault()?.offset ?? 0); return ((endTimeObjects < endTimeLines ? endTimeObjects : endTimeLines) + MILLISECOND_MARGIN); }
private static double GetStartTime(BeatmapSet aBeatmapSet) { double startTimeObjects = aBeatmapSet.beatmaps.Min(aBeatmap => aBeatmap.hitObjects.FirstOrDefault()?.time ?? 0); double startTimeLines = aBeatmapSet.beatmaps.Min(aBeatmap => aBeatmap.timingLines.FirstOrDefault()?.offset ?? 0); return ((startTimeObjects < startTimeLines ? startTimeObjects : startTimeLines) - MILLISECOND_MARGIN); }
/// <summary> /// Prepares a download object for a set from bloodcat or mirror if defined /// </summary> public static BeatmapDownload PrepareDownloadSet(BeatmapSet set, string mirror) { Uri downloadUri; if (string.IsNullOrEmpty(mirror)) { downloadUri = new Uri("http://bloodcat.com/osu/s/" + set.Id); } else { downloadUri = new Uri(mirror.Replace("%s", set.Id)); } return(new BeatmapDownload(set, downloadUri)); }
/// <summary> Returns whether the given skin name is used in the given beatmapset (including animations). </summary> public static bool IsUsed(string elementName, BeatmapSet beatmapSet) { if (!isInitialized) { Initialize(); } // Find the respective condition for the skin element to be used. SkinCondition?skinCondition = GetSkinCondition(elementName); // If the condition is null, the skin element is unrecognized and as such not used. return (skinCondition is SkinCondition condition && (condition.isUsed == null || condition.isUsed(beatmapSet))); }
private static bool checkAndPromptIfHaveMap(BeatmapSet set) { // check for already have if (set.AlreadyHave) { MessageBoxResult prompt = MessageBox.Show($"You already have this beatmap {set.Title} ({set.Mapper}). Do you wish to redownload it?", "NexDirect - Cancel Download", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (prompt == MessageBoxResult.No) { return(false); } return(true); } return(true); }
private static string RenderTimelineComparison(BeatmapSet aBeatmapSet) { return (RenderContainer("Timeline Comparison (Prototype)", RenderField("Navigation", RenderField("Move timeline", "Click & drag" ), RenderField("Move timeline faster", "Click & drag + Shift" ), RenderField("Move timeline slower", "Click & drag + Ctrl" ) ), RenderField("Timestamps", RenderField("See timestamp", "Hover" ), RenderField("Goto timestamp", "Alt + Left Click" ), RenderField("Copy timestamp", "Alt + Right Click" ) ), RenderField("Hit sounds", RenderField("Red lines", "Clap" ), RenderField("Green lines", "Finish" ), RenderField("Blue lines", "Whistle" ) ), Div("overview-timeline-top", RenderTop(aBeatmapSet) ), Div("overview-timeline-content", RenderContent(aBeatmapSet) ), Div("overview-timeline-footer", RenderFooter(aBeatmapSet) ) )); }
/// <summary> Returns a list of issues sorted by level, in the given beatmap set. </summary> public static List <Issue> GetBeatmapSetIssues(BeatmapSet aBeatmapSet) { if (!CheckerRegistry.GetChecks().Any()) { LoadCheckDLLs(); } ConcurrentBag <Issue> issueBag = new ConcurrentBag <Issue>(); TryGetIssuesParallel(CheckerRegistry.GetGeneralChecks(), aGeneralCheck => { foreach (Issue issue in aGeneralCheck.GetIssues(aBeatmapSet).OrderBy(anIssue => anIssue.level).Reverse()) { issueBag.Add(issue.WithOrigin(aGeneralCheck)); } }); Parallel.ForEach(aBeatmapSet.beatmaps, aBeatmap => { Track beatmapTrack = new Track("Checking for issues in " + aBeatmap + "..."); TryGetIssuesParallel(CheckerRegistry.GetBeatmapChecks(), aBeatmapCheck => { if (((BeatmapCheckMetadata)aBeatmapCheck.GetMetadata()).Modes.Contains(aBeatmap.generalSettings.mode)) { foreach (Issue issue in aBeatmapCheck.GetIssues(aBeatmap).OrderBy(anIssue => anIssue.level).Reverse()) { issueBag.Add(issue.WithOrigin(aBeatmapCheck)); } } }); beatmapTrack.Complete(); }); TryGetIssuesParallel(CheckerRegistry.GetBeatmapSetChecks(), aBeatmapSetCheck => { if (aBeatmapSet.beatmaps.Any(aBeatmap => ((BeatmapCheckMetadata)aBeatmapSetCheck.GetMetadata()).Modes.Contains(aBeatmap.generalSettings.mode))) { foreach (Issue issue in aBeatmapSetCheck.GetIssues(aBeatmapSet).OrderBy(anIssue => anIssue.level).Reverse()) { issueBag.Add(issue.WithOrigin(aBeatmapSetCheck)); } } }); return(issueBag.OrderByDescending(anIssue => anIssue.level).ToList()); }
/// <summary> /// Plays preview audio of a specific beatmap set to the waveout interface /// </summary> public static async Task <WaveOut> PlayPreviewAudio(BeatmapSet set, float?volume = null) { using (var client = new HttpClient()) { try { var response = await client.GetAsync("http://b.ppy.sh/preview/" + set.Id + ".mp3"); response.EnsureSuccessStatusCode(); Stream audioData = await response.Content.ReadAsStreamAsync(); return(AudioManager.PlayMp3Stream(audioData, volume)); } catch { return(null); } // meh audio previews arent that important, and sometimes they dont exist } }
public static string Render(BeatmapSet aBeatmapSet) { return(String.Concat( RenderBeatmapInfo(aBeatmapSet), Div("paste-separator"), RenderTimelineComparison(aBeatmapSet), RenderSnappings(aBeatmapSet), RenderMetadata(aBeatmapSet), RenderGeneralSettings(aBeatmapSet), RenderDifficultySettings(aBeatmapSet), RenderStatistics(aBeatmapSet), RenderResources(aBeatmapSet), RenderColourSettings(aBeatmapSet), Div("overview-footer") )); }
private IEnumerable <Issue> GetInconsistency(Beatmap beatmap, Beatmap otherBeatmap, BeatmapSet beatmapSet, InconsistencyTemplate inconsistency) { if (inconsistency.Condition == null || inconsistency.Condition(beatmap, otherBeatmap, beatmapSet)) { string value = inconsistency.Value(beatmap).ToString(); string otherValue = inconsistency.Value(otherBeatmap).ToString(); if (value != otherValue) { yield return(new Issue(GetTemplate(inconsistency.template), beatmap, inconsistency.name, value, otherBeatmap, otherValue)); } } }
private static string RenderFooter(BeatmapSet aBeatmapSet) { return (Div("overview-timeline-slider") + Div("overview-timeline-buttons", DivAttr("overview-timeline-button plus-icon", Tooltip("Zooms in timelines.") ), DivAttr("overview-timeline-button minus-icon", Tooltip("Zooms out timelines.") ), Div("overview-timeline-buttons-zoomamount", "1×" ) )); }
public override IEnumerable <Issue> GetIssues(BeatmapSet aBeatmapSet) { foreach (Issue issue in Common.GetTagOsuIssues( aBeatmapSet, aBeatmap => aBeatmap.backgrounds.Count > 0 ? aBeatmap.backgrounds.Select(aBg => aBg.path) : null, aTemplateArg => GetTemplate(aTemplateArg), aTagFile => { // Executes for each non-faulty background file used in one of the beatmaps in the set. List <Issue> issues = new List <Issue>(); if (aTagFile.file.Properties.PhotoWidth > 2560 || aTagFile.file.Properties.PhotoHeight > 1440) { issues.Add(new Issue(GetTemplate("Too high"), null, aTagFile.templateArgs[0], aTagFile.file.Properties.PhotoWidth, aTagFile.file.Properties.PhotoHeight)); } else if ( aTagFile.file.Properties.PhotoWidth < 1024 || aTagFile.file.Properties.PhotoHeight < 640) { issues.Add(new Issue(GetTemplate("Very low"), null, aTagFile.templateArgs[0], aTagFile.file.Properties.PhotoWidth, aTagFile.file.Properties.PhotoHeight)); } // Most operating systems define 1 KB as 1024 B and 1 MB as 1024 KB, // not 10^(3x) which the prefixes usually mean, but 2^(10x), since binary is more efficient for circuits, // so since this is what your computer uses we'll use this too. double megaBytes = new FileInfo(aTagFile.file.Name).Length / Math.Pow(1024, 2); if (megaBytes > 2.5) { issues.Add(new Issue(GetTemplate("File size"), null, aTagFile.templateArgs[0], FormattableString.Invariant($"{megaBytes:0.##}"))); } return(issues); })) { // Returns issues from both non-faulty and faulty files. yield return(issue); } }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { string audioPath = beatmapSet.GetAudioFilePath(); string audioName = beatmapSet.GetAudioFileName(); if (audioPath == null) { yield break; } ManagedBass.ChannelType actualFormat = 0; Exception exception = null; try { actualFormat = AudioBASS.GetFormat(audioPath); } catch (Exception ex) { exception = ex; } if (exception != null) { yield return(new Issue(GetTemplate("Exception"), null, audioName, Common.ExceptionTag(exception))); } else if ((ManagedBass.ChannelType.MP3 & actualFormat) != ManagedBass.ChannelType.MP3 && (ManagedBass.ChannelType.OGG & actualFormat) != ManagedBass.ChannelType.OGG) { yield return(new Issue(GetTemplate("Incorrect Format"), null, audioName, AudioBASS.EnumToString(actualFormat))); } else if (!audioName.ToLower().EndsWith(".mp3") && (ManagedBass.ChannelType.MP3 & actualFormat) == ManagedBass.ChannelType.MP3) { yield return(new Issue(GetTemplate("Incorrect Extension"), null, audioName, AudioBASS.EnumToString(actualFormat), ".mp3")); } else if (!audioName.ToLower().EndsWith(".ogg") && (ManagedBass.ChannelType.OGG & actualFormat) == ManagedBass.ChannelType.OGG) { yield return(new Issue(GetTemplate("Incorrect Extension"), null, audioName, AudioBASS.EnumToString(actualFormat), ".ogg")); } }
/// <summary> Returns whether the given skin name is used in the given beatmapset (including animations). </summary> public static bool IsUsed(string anElementName, BeatmapSet aBeatmapSet) { if (!isInitialized) { Initialize(); } // find the tuple that contains the element name Tuple <string[], Func <BeatmapSet, bool> > skinCondition = null; foreach (Tuple <string[], Func <BeatmapSet, bool> > conditionalTuple in conditionalTuples.ToList()) { foreach (string elementName in conditionalTuple.Item1) { if (elementName.ToLower() == anElementName.ToLower()) { skinCondition = conditionalTuple; } // animation frames, i.e. "followpoint-{n}.png" if (elementName.Contains("{n}")) { int startIndex = elementName.IndexOf("{n}"); if (startIndex != -1 && anElementName.Length > startIndex && anElementName.IndexOf('.', startIndex) != -1) { int endIndex = anElementName.IndexOf('.', startIndex); string frame = anElementName.Substring(startIndex, endIndex - startIndex); if (elementName.Replace("{n}", frame).ToLower() == anElementName) { skinCondition = conditionalTuple; } } } } } // if it's use condition matches, it's used if (skinCondition != null && (skinCondition.Item2 == null || skinCondition.Item2(aBeatmapSet))) { return(true); } return(false); }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { if (!beatmapSet.beatmaps.Any()) { yield break; } var refBeatmap = beatmapSet.beatmaps[0]; foreach (var marker in Markers) { foreach (Issue issue in GetFormattingIssues(refBeatmap.metadataSettings, marker)) { yield return(issue); } } }
public DirectDownload(MainWindow mw, BeatmapSet bs) { InitializeComponent(); set = bs; _mw = mw; Title = $"{set.Artist} - {set.Title} <{set.Mapper}> :: NexDirect Download"; previewImage.Source = new BitmapImage(bs.PreviewImage); songInfoLabel.Content = $"{set.Artist} - {set.Title}"; mapperInfoLabel.Content = $"(mapped by {set.Mapper})"; if (SettingManager.Get("overlayMode")) // overlay & only if osu! is open. { initOverlayMode(); } }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { foreach (Beatmap beatmap in beatmapSet.beatmaps) { foreach (string possessor in GetAllPossessors(beatmap.metadataSettings.version)) { if (beatmap.metadataSettings.IsCoveredByTags(possessor) || beatmap.metadataSettings.creator.ToLower() == possessor.ToLower()) { continue; } yield return(new Issue(GetTemplate("Warning"), null, beatmap.metadataSettings.version, possessor.ToLower().Replace(" ", "_"))); } } }
public override IEnumerable <Issue> GetIssues(BeatmapSet beatmapSet) { if (beatmapSet.GetAudioFilePath() != null) { foreach (var issue in GetIssue(beatmapSet, beatmapSet.GetAudioFilePath())) { yield return(issue); } } foreach (string hitSoundFile in beatmapSet.hitSoundFiles) { string hitSoundPath = Path.Combine(beatmapSet.songPath, hitSoundFile); ManagedBass.ChannelType hitSoundFormat = 0; Issue errorIssue = null; try { hitSoundFormat = AudioBASS.GetFormat(hitSoundPath); } catch (Exception exception) { errorIssue = new Issue(GetTemplate("Exception"), null, PathStatic.RelativePath(hitSoundPath, beatmapSet.songPath), Common.ExceptionTag(exception)); } if (errorIssue != null) { yield return(errorIssue); continue; } if ((hitSoundFormat & ManagedBass.ChannelType.OGG) != 0 && (hitSoundFormat & ManagedBass.ChannelType.MP3) != 0) { continue; } foreach (var issue in GetIssue(beatmapSet, hitSoundPath, true)) { yield return(issue); } } }
public static void AddOrUpdate(this DbSet <BeatmapSet> dbSet, BeatmapSet data) { var context = dbSet.GetContext(); var entities = dbSet.AsNoTracking().Where(set => set.SetId == data.SetId); var dbVal = entities.FirstOrDefault(); if (dbVal != null) { context.Entry(dbVal).CurrentValues.SetValues(data); context.Entry(dbVal).State = EntityState.Modified; return; } dbSet.Add(data); }