From 78692dc684e4efa337cdbfc12b02caa2eff6a821 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 10 Aug 2020 05:21:10 +0200 Subject: [PATCH 01/37] Initial commit --- osu.Game/Beatmaps/BeatmapManager.cs | 6 +++- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 33 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index b4b341634c..06acd4e9f2 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -26,6 +26,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; using Decoder = osu.Game.Beatmaps.Formats.Decoder; namespace osu.Game.Beatmaps @@ -201,7 +202,10 @@ namespace osu.Game.Beatmaps using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(beatmapContent).Encode(sw); + { + var skin = new LegacyBeatmapSkin(info, Files.Store, audioManager); + new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); + } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 57555cce90..8c96e59f30 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Skinning; using osuTK; namespace osu.Game.Beatmaps.Formats @@ -22,10 +23,12 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; + private readonly LegacyBeatmapSkin beatmapSkin; - public LegacyBeatmapEncoder(IBeatmap beatmap) + public LegacyBeatmapEncoder(IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin = null) { this.beatmap = beatmap; + this.beatmapSkin = beatmapSkin; if (beatmap.BeatmapInfo.RulesetID < 0 || beatmap.BeatmapInfo.RulesetID > 3) throw new ArgumentException("Only beatmaps in the osu, taiko, catch, or mania rulesets can be encoded to the legacy beatmap format.", nameof(beatmap)); @@ -53,6 +56,9 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(); handleControlPoints(writer); + writer.WriteLine(); + handleComboColours(writer); + writer.WriteLine(); handleHitObjects(writer); } @@ -196,6 +202,31 @@ namespace osu.Game.Beatmaps.Formats } } + private void handleComboColours(TextWriter writer) + { + if (beatmapSkin == null) + return; + + var colours = beatmapSkin.Configuration.ComboColours; + + if (colours.Count == 0) + return; + + writer.WriteLine("[Colours]"); + + for (var i = 0; i < colours.Count; i++) + { + var comboColour = colours[i]; + + var r = (byte)(comboColour.R * byte.MaxValue); + var g = (byte)(comboColour.G * byte.MaxValue); + var b = (byte)(comboColour.B * byte.MaxValue); + var a = (byte)(comboColour.A * byte.MaxValue); + + writer.WriteLine($"Combo{i}: {r},{g},{b},{a}"); + } + } + private void handleHitObjects(TextWriter writer) { if (beatmap.HitObjects.Count == 0) From 139c0c75f87e03ad4d86fd524e61c4dea79f0e81 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:37:25 +0200 Subject: [PATCH 02/37] Add documentation for constructor --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 8c96e59f30..3e744056bb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; using System.Text; +using JetBrains.Annotations; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Legacy; @@ -25,7 +26,9 @@ namespace osu.Game.Beatmaps.Formats private readonly IBeatmap beatmap; private readonly LegacyBeatmapSkin beatmapSkin; - public LegacyBeatmapEncoder(IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin = null) + /// The beatmap to encode + /// An optional beatmap skin, for encoding the beatmap's combo colours. + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin beatmapSkin) { this.beatmap = beatmap; this.beatmapSkin = beatmapSkin; From 8ffaa49839bdf3902e57c57b0ff429b8c91a2fb1 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:37:33 +0200 Subject: [PATCH 03/37] Handle additional null case --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 3e744056bb..eb148794de 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -207,12 +207,9 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - if (beatmapSkin == null) - return; + var colours = beatmapSkin?.Configuration.ComboColours; - var colours = beatmapSkin.Configuration.ComboColours; - - if (colours.Count == 0) + if (colours == null || colours.Count == 0) return; writer.WriteLine("[Colours]"); From 69590113d62c54ec56c86c8bc529a49b0c2e337a Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Wed, 12 Aug 2020 06:38:05 +0200 Subject: [PATCH 04/37] Temporary changes --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 +++++++- osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs | 8 +++++++- osu.Game/Screens/Edit/EditorChangeHandler.cs | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 30331e98d2..fba63f8539 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -10,6 +10,7 @@ using System.Text; using NUnit.Framework; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; +using osu.Framework.IO.Stores; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; @@ -19,6 +20,7 @@ using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; +using osu.Game.Skinning; using osu.Game.Tests.Resources; namespace osu.Game.Tests.Beatmaps.Formats @@ -61,7 +63,11 @@ namespace osu.Game.Tests.Beatmaps.Formats var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(beatmap).Encode(writer); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); + } stream.Position = 0; diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index ff17f23d50..74b6f66d85 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text; using NUnit.Framework; +using osu.Framework.IO.Stores; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; @@ -14,6 +15,7 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit; +using osu.Game.Skinning; using osuTK; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -351,7 +353,11 @@ namespace osu.Game.Tests.Editing using (var encoded = new MemoryStream()) { using (var sw = new StreamWriter(encoded)) - new LegacyBeatmapEncoder(beatmap).Encode(sw); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(beatmap, skin).Encode(sw); + } return encoded.ToArray(); } diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 1553c2d2ef..6393093c74 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -6,8 +6,10 @@ using System.Collections.Generic; using System.IO; using System.Text; using osu.Framework.Bindables; +using osu.Framework.IO.Stores; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -85,7 +87,11 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(editorBeatmap).Encode(sw); + using (var rs = new ResourceStore()) + { + var skin = new LegacyBeatmapSkin(editorBeatmap.BeatmapInfo, rs, null); + new LegacyBeatmapEncoder(editorBeatmap, skin).Encode(sw); + } savedStates.Add(stream.ToArray()); } From c4a7fac760efde4622956f1fa3c581e469c8e508 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 22:03:24 +0200 Subject: [PATCH 05/37] Add required parameters and other various changes --- .../Formats/LegacyBeatmapEncoderTest.cs | 30 ++++++++++++++----- .../Beatmaps/IO/ImportBeatmapTest.cs | 5 ++-- .../Editing/EditorChangeHandlerTest.cs | 6 ++-- .../Editing/LegacyEditorBeatmapPatcherTest.cs | 8 +---- osu.Game/Beatmaps/BeatmapManager.cs | 4 +-- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 13 ++++---- osu.Game/Screens/Edit/Editor.cs | 7 +++-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 11 +++---- 8 files changed, 51 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index fba63f8539..38f730995e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -28,13 +28,25 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestFixture] public class LegacyBeatmapEncoderTest { - private static IEnumerable allBeatmaps => TestResources.GetStore().GetAvailableResources().Where(res => res.EndsWith(".osu")); + private static readonly DllResourceStore resource_store = TestResources.GetStore(); + + private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); + + private static Stream beatmapSkinStream = resource_store.GetStream("skin.ini"); + + private ISkin skin; + + [SetUp] + public void Init() + { + skin = decodeSkinFromLegacy(beatmapSkinStream); + } [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); + var decoded = decodeBeatmapFromLegacy(TestResources.GetStore().GetStream(name)); + var decodedAfterEncode = decodeBeatmapFromLegacy(encodeToLegacy(decoded, skin)); sort(decoded); sort(decodedAfterEncode); @@ -52,20 +64,24 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private IBeatmap decodeFromLegacy(Stream stream) + private IBeatmap decodeBeatmapFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader)); } - private Stream encodeToLegacy(IBeatmap beatmap) + private ISkin decodeSkinFromLegacy(Stream stream) + { + using (var reader = new LineBufferedReader(stream)) + return new LegacySkin(SkinInfo.Default, resource_store, null); + } + + private Stream encodeToLegacy(IBeatmap beatmap, ISkin skin) { var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - using (var rs = new ResourceStore()) { - var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); } diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 0151678db3..17271184c0 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -730,7 +730,8 @@ namespace osu.Game.Tests.Beatmaps.IO BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; var beatmapInfo = setToUpdate.Beatmaps.First(b => b.RulesetID == 0); - Beatmap beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap; + var workingBeatmap = manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)); + Beatmap beatmapToUpdate = (Beatmap)workingBeatmap.Beatmap; BeatmapSetFileInfo fileToUpdate = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename)); string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash; @@ -738,7 +739,7 @@ namespace osu.Game.Tests.Beatmaps.IO beatmapToUpdate.HitObjects.Clear(); beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 }); - manager.Save(beatmapInfo, beatmapToUpdate); + manager.Save(beatmapInfo, beatmapToUpdate, workingBeatmap.Skin); // Check that the old file reference has been removed Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID)); diff --git a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs index feda1ae0e9..6d708ce838 100644 --- a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs +++ b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestSaveRestoreState() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); Assert.That(handler.CanRedo.Value, Is.False); @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesSaved() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesExceeded() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); Assert.That(handler.CanUndo.Value, Is.False); diff --git a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs index 74b6f66d85..b491157627 100644 --- a/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs +++ b/osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text; using NUnit.Framework; -using osu.Framework.IO.Stores; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; @@ -15,7 +14,6 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit; -using osu.Game.Skinning; using osuTK; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -353,11 +351,7 @@ namespace osu.Game.Tests.Editing using (var encoded = new MemoryStream()) { using (var sw = new StreamWriter(encoded)) - using (var rs = new ResourceStore()) - { - var skin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, rs, null); - new LegacyBeatmapEncoder(beatmap, skin).Encode(sw); - } + new LegacyBeatmapEncoder(beatmap, null).Encode(sw); return encoded.ToArray(); } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 06acd4e9f2..bd757d30ca 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,7 +195,8 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - public void Save(BeatmapInfo info, IBeatmap beatmapContent) + /// Optional beatmap skin for inline skin configuration in beatmap files. + public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin skin) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); @@ -203,7 +204,6 @@ namespace osu.Game.Beatmaps { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) { - var skin = new LegacyBeatmapSkin(info, Files.Store, audioManager); new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index eb148794de..716f1bc814 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -24,14 +24,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly LegacyBeatmapSkin beatmapSkin; + private readonly ISkin skin; /// The beatmap to encode - /// An optional beatmap skin, for encoding the beatmap's combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin beatmapSkin) + /// An optional skin, for encoding the beatmap's combo colours. This will only work if the parameter is a type of . + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) { this.beatmap = beatmap; - this.beatmapSkin = beatmapSkin; + this.skin = skin; if (beatmap.BeatmapInfo.RulesetID < 0 || beatmap.BeatmapInfo.RulesetID > 3) throw new ArgumentException("Only beatmaps in the osu, taiko, catch, or mania rulesets can be encoded to the legacy beatmap format.", nameof(beatmap)); @@ -207,7 +207,10 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - var colours = beatmapSkin?.Configuration.ComboColours; + if (!(skin is LegacyBeatmapSkin legacySkin)) + return; + + var colours = legacySkin?.Configuration.ComboColours; if (colours == null || colours.Count == 0) return; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d92f3922c3..d52d832bf3 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -33,6 +33,7 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Play; +using osu.Game.Skinning; using osu.Game.Users; namespace osu.Game.Screens.Edit @@ -64,6 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; + private ISkin beatmapSkin; private DependencyContainer dependencies; @@ -92,6 +94,7 @@ namespace osu.Game.Screens.Edit try { playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); + beatmapSkin = Beatmap.Value.Skin; } catch (Exception e) { @@ -104,7 +107,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); - changeHandler = new EditorChangeHandler(editorBeatmap); + changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); EditorMenuBar menuBar; @@ -399,7 +402,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, Beatmap.Value.Skin); private void exportBeatmap() { diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 6393093c74..f305d2a15d 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Text; using osu.Framework.Bindables; -using osu.Framework.IO.Stores; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; using osu.Game.Skinning; @@ -27,6 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; + private readonly ISkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -36,7 +36,8 @@ namespace osu.Game.Screens.Edit /// Creates a new . /// /// The to track the s of. - public EditorChangeHandler(EditorBeatmap editorBeatmap) + /// The skin to track the inline skin configuration of. + public EditorChangeHandler(EditorBeatmap editorBeatmap, ISkin beatmapSkin) { this.editorBeatmap = editorBeatmap; @@ -46,6 +47,8 @@ namespace osu.Game.Screens.Edit patcher = new LegacyEditorBeatmapPatcher(editorBeatmap); + this.beatmapSkin = beatmapSkin; + // Initial state. SaveState(); } @@ -87,10 +90,8 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - using (var rs = new ResourceStore()) { - var skin = new LegacyBeatmapSkin(editorBeatmap.BeatmapInfo, rs, null); - new LegacyBeatmapEncoder(editorBeatmap, skin).Encode(sw); + new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); } savedStates.Add(stream.ToArray()); From 0e8411f76c156110fb7e693292d5649dd2d17265 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 22:06:26 +0200 Subject: [PATCH 06/37] Rename fields and make readonly --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 38f730995e..63fdf2a8ae 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -32,14 +32,13 @@ namespace osu.Game.Tests.Beatmaps.Formats private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); - private static Stream beatmapSkinStream = resource_store.GetStream("skin.ini"); - + private static readonly Stream beatmap_skin_stream = resource_store.GetStream("skin.ini"); private ISkin skin; [SetUp] public void Init() { - skin = decodeSkinFromLegacy(beatmapSkinStream); + skin = decodeSkinFromLegacy(beatmap_skin_stream); } [TestCaseSource(nameof(allBeatmaps))] @@ -76,14 +75,12 @@ namespace osu.Game.Tests.Beatmaps.Formats return new LegacySkin(SkinInfo.Default, resource_store, null); } - private Stream encodeToLegacy(IBeatmap beatmap, ISkin skin) + private Stream encodeToLegacy(IBeatmap beatmap, ISkin beatmapSkin) { var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { - new LegacyBeatmapEncoder(beatmap, skin).Encode(writer); - } + new LegacyBeatmapEncoder(beatmap, beatmapSkin).Encode(writer); stream.Position = 0; From 3a6e378a08ce5fde5b23ee302f48ba4afdf4f113 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 23:41:53 +0200 Subject: [PATCH 07/37] Change skin testing --- .../Formats/LegacyBeatmapEncoderTest.cs | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 63fdf2a8ae..6ede30d7d8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -32,25 +32,28 @@ namespace osu.Game.Tests.Beatmaps.Formats private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); - private static readonly Stream beatmap_skin_stream = resource_store.GetStream("skin.ini"); - private ISkin skin; - - [SetUp] - public void Init() - { - skin = decodeSkinFromLegacy(beatmap_skin_stream); - } - [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeBeatmapFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeBeatmapFromLegacy(encodeToLegacy(decoded, skin)); + var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); + var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); - sort(decoded); - sort(decodedAfterEncode); + sort(decoded.beatmap); + sort(decodedAfterEncode.beatmap); - Assert.That(decodedAfterEncode.Serialize(), Is.EqualTo(decoded.Serialize())); + Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); + + areSkinsEqual(decoded.beatmapSkin, decodedAfterEncode.beatmapSkin); + } + + private void areSkinsEqual(LegacySkin expected, LegacySkin actual) + { + var expectedColours = expected.Configuration.ComboColours; + var actualColours = actual.Configuration.ComboColours; + + Assert.AreEqual(expectedColours.Count, actualColours.Count); + for (int i = 0; i < expectedColours.Count; i++) + Assert.AreEqual(expectedColours[i], actualColours[i]); } private void sort(IBeatmap beatmap) @@ -63,20 +66,19 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private IBeatmap decodeBeatmapFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) - return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader)); + { + var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); + var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, resource_store, null); + return (convert(beatmap), beatmapSkin); + } } - private ISkin decodeSkinFromLegacy(Stream stream) - { - using (var reader = new LineBufferedReader(stream)) - return new LegacySkin(SkinInfo.Default, resource_store, null); - } - - private Stream encodeToLegacy(IBeatmap beatmap, ISkin beatmapSkin) + private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) { + var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)) From 48bdbb0cfbd9f94b8d9b4182290a1dec66c7c256 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 15 Aug 2020 23:46:10 +0200 Subject: [PATCH 08/37] Use existing field in Editor --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d52d832bf3..a585db1ee9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -402,7 +402,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, Beatmap.Value.Skin); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, beatmapSkin); private void exportBeatmap() { From 434354c44c2ab3f0bde6d0d04ade551b0a4d00ac Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 16 Aug 2020 00:21:26 +0200 Subject: [PATCH 09/37] Properly implement SkinConfiguration equality --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 13 +------------ osu.Game/Skinning/SkinConfiguration.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 6ede30d7d8..66b39648e5 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -42,18 +42,7 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode.beatmap); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - - areSkinsEqual(decoded.beatmapSkin, decodedAfterEncode.beatmapSkin); - } - - private void areSkinsEqual(LegacySkin expected, LegacySkin actual) - { - var expectedColours = expected.Configuration.ComboColours; - var actualColours = actual.Configuration.ComboColours; - - Assert.AreEqual(expectedColours.Count, actualColours.Count); - for (int i = 0; i < expectedColours.Count; i++) - Assert.AreEqual(expectedColours[i], actualColours[i]); + Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } private void sort(IBeatmap beatmap) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a55870aa6d..4b29111504 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -10,7 +12,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IHasComboColours, IHasCustomColours + public class SkinConfiguration : IHasComboColours, IHasCustomColours, IEquatable { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -48,5 +50,13 @@ namespace osu.Game.Skinning public Dictionary CustomColours { get; set; } = new Dictionary(); public readonly Dictionary ConfigDictionary = new Dictionary(); + + public bool Equals(SkinConfiguration other) + { + return other != null && + ConfigDictionary.SequenceEqual(other.ConfigDictionary) && + ComboColours.SequenceEqual(other.ComboColours) && + CustomColours.SequenceEqual(other.CustomColours); + } } } From cfd82104dbe5f23b9a92f2129441f8a328bc80a1 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 16 Aug 2020 01:00:28 +0200 Subject: [PATCH 10/37] Minor changes and improvements --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 4 ++-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 2 -- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 66b39648e5..db18f9b444 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacySkin beatmapSkin) decodeFromLegacy(Stream stream) { using (var reader = new LineBufferedReader(stream)) { @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, LegacySkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index f305d2a15d..0489236d45 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -90,9 +90,7 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); - } savedStates.Add(stream.ToArray()); } diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 4b29111504..a48d713771 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -56,7 +56,7 @@ namespace osu.Game.Skinning return other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && - CustomColours.SequenceEqual(other.CustomColours); + CustomColours?.SequenceEqual(other.CustomColours) == true; } } } From e6646b9877883560187415b1781e3a726da1ca43 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:08:02 +0200 Subject: [PATCH 11/37] Resolve review comments --- .../Formats/LegacyBeatmapEncoderTest.cs | 31 +++++++++++++------ .../Beatmaps/IO/ImportBeatmapTest.cs | 5 ++- osu.Game/Beatmaps/BeatmapManager.cs | 12 +++++-- .../Beatmaps/Formats/IHasCustomColours.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 25 ++++++++------- osu.Game/Screens/Edit/Editor.cs | 4 +-- osu.Game/Screens/Edit/EditorChangeHandler.cs | 4 +-- .../Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 16 +++++----- 9 files changed, 59 insertions(+), 42 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index db18f9b444..4e9e6743c9 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -28,25 +28,27 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestFixture] public class LegacyBeatmapEncoderTest { - private static readonly DllResourceStore resource_store = TestResources.GetStore(); + private static readonly DllResourceStore beatmaps_resource_store = TestResources.GetStore(); - private static IEnumerable allBeatmaps = resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); + private static IEnumerable allBeatmaps = beatmaps_resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name)); - var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded)); + var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name), name); + var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); - sort(decoded.beatmap); - sort(decodedAfterEncode.beatmap); + sort(decoded); + sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort(IBeatmap beatmap) + private void sort((IBeatmap, LegacyBeatmapSkin) bs) { + var (beatmap, beatmapSkin) = bs; + // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in beatmap.ControlPointInfo.Groups) { @@ -55,17 +57,26 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacySkin beatmapSkin) decodeFromLegacy(Stream stream) + private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream, string name) { using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, resource_store, null); + beatmap.BeatmapInfo.BeatmapSet.Files = new List + { + new BeatmapSetFileInfo + { + Filename = name, + FileInfo = new osu.Game.IO.FileInfo() { Hash = name } + } + }; + + var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, beatmaps_resource_store, null); return (convert(beatmap), beatmapSkin); } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacySkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 17271184c0..0151678db3 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -730,8 +730,7 @@ namespace osu.Game.Tests.Beatmaps.IO BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0]; var beatmapInfo = setToUpdate.Beatmaps.First(b => b.RulesetID == 0); - var workingBeatmap = manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)); - Beatmap beatmapToUpdate = (Beatmap)workingBeatmap.Beatmap; + Beatmap beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap; BeatmapSetFileInfo fileToUpdate = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename)); string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash; @@ -739,7 +738,7 @@ namespace osu.Game.Tests.Beatmaps.IO beatmapToUpdate.HitObjects.Clear(); beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 }); - manager.Save(beatmapInfo, beatmapToUpdate, workingBeatmap.Skin); + manager.Save(beatmapInfo, beatmapToUpdate); // Check that the old file reference has been removed Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID)); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index bd757d30ca..86d35749ac 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,8 +195,8 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - /// Optional beatmap skin for inline skin configuration in beatmap files. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin skin) + /// The beatmap content to write, or null if not to be changed. + public void Save(BeatmapInfo info, IBeatmap beatmapContent, LegacyBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); @@ -204,7 +204,13 @@ namespace osu.Game.Beatmaps { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) { - new LegacyBeatmapEncoder(beatmapContent, skin).Encode(sw); + if (beatmapSkin == null) + { + var workingBeatmap = GetWorkingBeatmap(info); + beatmapSkin = (workingBeatmap.Skin is LegacyBeatmapSkin legacy) ? legacy : null; + } + + new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw); } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs index 8f6c7dc328..1ac5ca83cb 100644 --- a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs +++ b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs @@ -8,6 +8,6 @@ namespace osu.Game.Beatmaps.Formats { public interface IHasCustomColours { - Dictionary CustomColours { get; set; } + IDictionary CustomColours { get; } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 716f1bc814..497c3c88d0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Beatmaps.Formats { @@ -24,11 +25,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly ISkin skin; + private readonly LegacyBeatmapSkin skin; - /// The beatmap to encode - /// An optional skin, for encoding the beatmap's combo colours. This will only work if the parameter is a type of . - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) + /// + /// Creates a new . + /// + /// The beatmap to encode. + /// An optional skin, for encoding the beatmap's combo colours. + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin skin) { this.beatmap = beatmap; this.skin = skin; @@ -210,7 +214,7 @@ namespace osu.Game.Beatmaps.Formats if (!(skin is LegacyBeatmapSkin legacySkin)) return; - var colours = legacySkin?.Configuration.ComboColours; + var colours = legacySkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; @@ -221,12 +225,11 @@ namespace osu.Game.Beatmaps.Formats { var comboColour = colours[i]; - var r = (byte)(comboColour.R * byte.MaxValue); - var g = (byte)(comboColour.G * byte.MaxValue); - var b = (byte)(comboColour.B * byte.MaxValue); - var a = (byte)(comboColour.A * byte.MaxValue); - - writer.WriteLine($"Combo{i}: {r},{g},{b},{a}"); + writer.Write(FormattableString.Invariant($"Combo{i}: ")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.R * byte.MaxValue)},")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.G * byte.MaxValue)},")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.B * byte.MaxValue)},")); + writer.WriteLine(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a585db1ee9..7bd6529897 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private ISkin beatmapSkin; + private LegacyBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -94,7 +94,6 @@ namespace osu.Game.Screens.Edit try { playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - beatmapSkin = Beatmap.Value.Skin; } catch (Exception e) { @@ -107,6 +106,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); + beatmapSkin = (Beatmap.Value.Skin is LegacyBeatmapSkin legacy) ? legacy : null; changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 0489236d45..1d10eaf5cb 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly ISkin beatmapSkin; + private readonly LegacyBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Edit /// /// The to track the s of. /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, ISkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap, LegacyBeatmapSkin beatmapSkin) { this.editorBeatmap = editorBeatmap; diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index af7d6007f3..f92da0b446 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public Dictionary CustomColours { get; set; } = new Dictionary(); + public IDictionary CustomColours { get; set; } = new SortedDictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a48d713771..9565eee827 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -12,7 +12,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IHasComboColours, IHasCustomColours, IEquatable + public class SkinConfiguration : IEquatable, IHasComboColours, IHasCustomColours { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -47,16 +47,14 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public Dictionary CustomColours { get; set; } = new Dictionary(); + public IDictionary CustomColours { get; set; } = new SortedDictionary(); - public readonly Dictionary ConfigDictionary = new Dictionary(); + public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); public bool Equals(SkinConfiguration other) - { - return other != null && - ConfigDictionary.SequenceEqual(other.ConfigDictionary) && - ComboColours.SequenceEqual(other.ComboColours) && - CustomColours?.SequenceEqual(other.CustomColours) == true; - } + => other != null + && ConfigDictionary.SequenceEqual(other.ConfigDictionary) + && ComboColours.SequenceEqual(other.ComboColours) + && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From 492be0e0169248794305cda313b187b1ca0c3894 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:23:10 +0200 Subject: [PATCH 12/37] Fix formatting --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 +++----- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 11 +++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 4e9e6743c9..f093180085 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -45,12 +45,10 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort((IBeatmap, LegacyBeatmapSkin) bs) + private void sort((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) tuple) { - var (beatmap, beatmapSkin) = bs; - // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. - foreach (var g in beatmap.ControlPointInfo.Groups) + foreach (var g in tuple.beatmap.ControlPointInfo.Groups) { ArrayList.Adapter((IList)g.ControlPoints).Sort( Comparer.Create((c1, c2) => string.Compare(c1.GetType().ToString(), c2.GetType().ToString(), StringComparison.Ordinal))); @@ -67,7 +65,7 @@ namespace osu.Game.Tests.Beatmaps.Formats new BeatmapSetFileInfo { Filename = name, - FileInfo = new osu.Game.IO.FileInfo() { Hash = name } + FileInfo = new osu.Game.IO.FileInfo { Hash = name } } }; diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index f92da0b446..baa7fa817c 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public IDictionary CustomColours { get; set; } = new SortedDictionary(); + public IDictionary CustomColours { get; } = new SortedDictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 9565eee827..27589577e6 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -47,14 +47,13 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public IDictionary CustomColours { get; set; } = new SortedDictionary(); + public IDictionary CustomColours { get; } = new SortedDictionary(); public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) - => other != null - && ConfigDictionary.SequenceEqual(other.ConfigDictionary) - && ComboColours.SequenceEqual(other.ComboColours) - && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null + && ConfigDictionary.SequenceEqual(other.ConfigDictionary) + && ComboColours.SequenceEqual(other.ComboColours) + && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From 8f9e090f4c02549c8ed613e8c70785eed38d17be Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 23 Aug 2020 15:39:48 +0200 Subject: [PATCH 13/37] Remove Indent --- osu.Game/Skinning/SkinConfiguration.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 27589577e6..2ac4dfa0c8 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,9 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null - && ConfigDictionary.SequenceEqual(other.ConfigDictionary) - && ComboColours.SequenceEqual(other.ComboColours) - && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && CustomColours?.SequenceEqual(other.CustomColours) == true; } } From da5853e7eb2c7dd95c8d5ca22ca4a0d4488ae731 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sat, 29 Aug 2020 10:25:43 +0200 Subject: [PATCH 14/37] Create a new BeatmapSetInfo when setting files --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index f093180085..dee4626cd0 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -60,12 +60,15 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - beatmap.BeatmapInfo.BeatmapSet.Files = new List + beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo { - new BeatmapSetFileInfo + Files = new List { - Filename = name, - FileInfo = new osu.Game.IO.FileInfo { Hash = name } + new BeatmapSetFileInfo + { + Filename = name, + FileInfo = new osu.Game.IO.FileInfo { Hash = name } + } } }; From e428144f736cdbbb818f9c001d31866fb975b1f2 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 11:34:50 +0200 Subject: [PATCH 15/37] Use IBeatmapSkin --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 4 ++-- osu.Game/Beatmaps/BeatmapManager.cs | 10 +--------- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 9 +++------ 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index dee4626cd0..8d5060e2fe 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); } - private void sort((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) tuple) + private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in tuple.beatmap.ControlPointInfo.Groups) @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 86d35749ac..89a776dd31 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -196,22 +196,14 @@ namespace osu.Game.Beatmaps /// The to save the content against. The file referenced by will be replaced. /// The content to write. /// The beatmap content to write, or null if not to be changed. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, LegacyBeatmapSkin beatmapSkin = null) + public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - { - if (beatmapSkin == null) - { - var workingBeatmap = GetWorkingBeatmap(info); - beatmapSkin = (workingBeatmap.Skin is LegacyBeatmapSkin legacy) ? legacy : null; - } - new LegacyBeatmapEncoder(beatmapContent, beatmapSkin).Encode(sw); - } stream.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 497c3c88d0..543d960300 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -25,14 +25,14 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; - private readonly LegacyBeatmapSkin skin; + private readonly IBeatmapSkin skin; /// /// Creates a new . /// /// The beatmap to encode. /// An optional skin, for encoding the beatmap's combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] LegacyBeatmapSkin skin) + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) { this.beatmap = beatmap; this.skin = skin; @@ -211,10 +211,7 @@ namespace osu.Game.Beatmaps.Formats private void handleComboColours(TextWriter writer) { - if (!(skin is LegacyBeatmapSkin legacySkin)) - return; - - var colours = legacySkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; + var colours = skin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; From 08321d8dec457381c1e52cab064dd304e309a1ac Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 11:37:43 +0200 Subject: [PATCH 16/37] Safe checking against ComboColours instead of CustomColours --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 2ac4dfa0c8..0f6162d6c4 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,6 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours.SequenceEqual(other.ComboColours) && CustomColours?.SequenceEqual(other.CustomColours) == true; + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours?.SequenceEqual(other.ComboColours) == true && CustomColours.SequenceEqual(other.CustomColours); } } From f5c82d41eb010912aebd758db6c4b3e9677ac01a Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:06:48 +0200 Subject: [PATCH 17/37] Remove if-cast --- osu.Game/Screens/Edit/Editor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7bd6529897..273ae67ffd 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private LegacyBeatmapSkin beatmapSkin; + private IBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); dependencies.CacheAs(editorBeatmap); - beatmapSkin = (Beatmap.Value.Skin is LegacyBeatmapSkin legacy) ? legacy : null; + beatmapSkin = Beatmap.Value.Skin; changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); dependencies.CacheAs(changeHandler); From b39ec74bb812f5c582936cb2ca9877700d786968 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:06 +0200 Subject: [PATCH 18/37] Scope down to IBeatmapSkin in EditorChangeHandler --- osu.Game/Screens/Edit/EditorChangeHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 1d10eaf5cb..60d869ec82 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly LegacyBeatmapSkin beatmapSkin; + private readonly IBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Edit /// /// The to track the s of. /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, LegacyBeatmapSkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap, IBeatmapSkin beatmapSkin) { this.editorBeatmap = editorBeatmap; From 7e57af3ca437b5ae7a053051eb3b64cc1c0bc0e4 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:46 +0200 Subject: [PATCH 19/37] Return true if both ComboColours are null --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 0f6162d6c4..18d970dd64 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -51,6 +51,6 @@ namespace osu.Game.Skinning public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ComboColours?.SequenceEqual(other.ComboColours) == true && CustomColours.SequenceEqual(other.CustomColours); + public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ((ComboColours == null && other.ComboColours == null) || ComboColours.SequenceEqual(other.ComboColours)) && CustomColours.SequenceEqual(other.CustomColours); } } From 1fdf8e62004f59ec098a793c6d1a8591cf053b37 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:07:58 +0200 Subject: [PATCH 20/37] Fix xmldoc in LegacyBeatmapEncoder --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 543d960300..8d7e509070 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -31,7 +31,7 @@ namespace osu.Game.Beatmaps.Formats /// Creates a new . /// /// The beatmap to encode. - /// An optional skin, for encoding the beatmap's combo colours. + /// The beatmap's skin, used for encoding combo colours. public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) { this.beatmap = beatmap; From 919d7b77855435bc90df339ac3c939550145ca96 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:08:13 +0200 Subject: [PATCH 21/37] Remove redundant call to TestResources --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 8d5060e2fe..b25f2f1fd3 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [TestCaseSource(nameof(allBeatmaps))] public void TestEncodeDecodeStability(string name) { - var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name), name); + var decoded = decodeFromLegacy(beatmaps_resource_store.GetStream(name), name); var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); sort(decoded); From 337037ab3b0f33474c1d9cc829b25b169a49337d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:08:52 +0200 Subject: [PATCH 22/37] Make test load actual beatmap's skin configuration --- .../Formats/LegacyBeatmapEncoderTest.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index b25f2f1fd3..bea21087c5 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - Assert.IsTrue(decoded.beatmapSkin.Configuration.Equals(decodedAfterEncode.beatmapSkin.Configuration)); + Assert.IsTrue(decodedAfterEncode.beatmapSkin.Configuration.Equals(decoded.beatmapSkin.Configuration)); } private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) @@ -55,11 +55,13 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private (IBeatmap beatmap, LegacyBeatmapSkin beatmapSkin) decodeFromLegacy(Stream stream, string name) + private (IBeatmap beatmap, TestLegacySkin beatmapSkin) decodeFromLegacy(Stream stream, string name) { using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); + + beatmap.BeatmapInfo.Path = name; beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo { Files = new List @@ -69,14 +71,22 @@ namespace osu.Game.Tests.Beatmaps.Formats Filename = name, FileInfo = new osu.Game.IO.FileInfo { Hash = name } } - } + }, }; - var beatmapSkin = new LegacyBeatmapSkin(beatmap.BeatmapInfo, beatmaps_resource_store, null); + var beatmapSkin = new TestLegacySkin(beatmap, beatmaps_resource_store, name); return (convert(beatmap), beatmapSkin); } } + private class TestLegacySkin : LegacySkin, IBeatmapSkin + { + public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) + : base(new SkinInfo() { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) + { + } + } + private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; From 7e668fc31a619ca1d89dc6532898433bf40efe07 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:11:49 +0200 Subject: [PATCH 23/37] Update osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs Co-authored-by: Salman Ahmed --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 8d7e509070..cae6a43cd4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -226,7 +226,8 @@ namespace osu.Game.Beatmaps.Formats writer.Write(FormattableString.Invariant($"{(byte)(comboColour.R * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.G * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.B * byte.MaxValue)},")); - writer.WriteLine(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); + writer.Write(FormattableString.Invariant($"{(byte)(comboColour.A * byte.MaxValue)}")); + writer.WriteLine(); } } From 43d144b7c00756a0cb0d94a7c88750614fcd97f6 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 16:23:00 +0200 Subject: [PATCH 24/37] Remove empty argument list --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index bea21087c5..dc91af72e8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Beatmaps.Formats private class TestLegacySkin : LegacySkin, IBeatmapSkin { public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) - : base(new SkinInfo() { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) + : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) { } } From db413686bbe7db6dadf72d71d54fe1def027427b Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 21:12:45 +0200 Subject: [PATCH 25/37] Add BeatmapSkin to EditorBeatmap --- osu.Game.Tests/Editing/EditorChangeHandlerTest.cs | 6 +++--- osu.Game/Screens/Edit/Editor.cs | 10 +++------- osu.Game/Screens/Edit/EditorBeatmap.cs | 6 +++++- osu.Game/Screens/Edit/EditorChangeHandler.cs | 9 ++------- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs index 6d708ce838..feda1ae0e9 100644 --- a/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs +++ b/osu.Game.Tests/Editing/EditorChangeHandlerTest.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestSaveRestoreState() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); Assert.That(handler.CanRedo.Value, Is.False); @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesSaved() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Editing [Test] public void TestMaxStatesExceeded() { - var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()), null); + var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap())); Assert.That(handler.CanUndo.Value, Is.False); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 273ae67ffd..b1f11d79f9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -33,7 +33,6 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Setup; using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Play; -using osu.Game.Skinning; using osu.Game.Users; namespace osu.Game.Screens.Edit @@ -65,7 +64,6 @@ namespace osu.Game.Screens.Edit private IBeatmap playableBeatmap; private EditorBeatmap editorBeatmap; private EditorChangeHandler changeHandler; - private IBeatmapSkin beatmapSkin; private DependencyContainer dependencies; @@ -103,11 +101,9 @@ namespace osu.Game.Screens.Edit return; } - AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); + AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, Beatmap.Value.Skin)); dependencies.CacheAs(editorBeatmap); - - beatmapSkin = Beatmap.Value.Skin; - changeHandler = new EditorChangeHandler(editorBeatmap, beatmapSkin); + changeHandler = new EditorChangeHandler(editorBeatmap); dependencies.CacheAs(changeHandler); EditorMenuBar menuBar; @@ -402,7 +398,7 @@ namespace osu.Game.Screens.Edit clock.SeekForward(!clock.IsRunning, amount); } - private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, beatmapSkin); + private void saveBeatmap() => beatmapManager.Save(playableBeatmap.BeatmapInfo, editorBeatmap, editorBeatmap.BeatmapSkin); private void exportBeatmap() { diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 23c8c9f605..a314d50e60 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -15,6 +15,7 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; +using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -47,6 +48,8 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; + public readonly IBeatmapSkin BeatmapSkin; + [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -54,9 +57,10 @@ namespace osu.Game.Screens.Edit private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap) + public EditorBeatmap(IBeatmap playableBeatmap, IBeatmapSkin beatmapSkin = null) { PlayableBeatmap = playableBeatmap; + BeatmapSkin = beatmapSkin; beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateBeatmapProcessor(PlayableBeatmap); diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 60d869ec82..927c823c64 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -8,7 +8,6 @@ using System.Text; using osu.Framework.Bindables; using osu.Game.Beatmaps.Formats; using osu.Game.Rulesets.Objects; -using osu.Game.Skinning; namespace osu.Game.Screens.Edit { @@ -26,7 +25,6 @@ namespace osu.Game.Screens.Edit private int currentState = -1; private readonly EditorBeatmap editorBeatmap; - private readonly IBeatmapSkin beatmapSkin; private int bulkChangesStarted; private bool isRestoring; @@ -36,8 +34,7 @@ namespace osu.Game.Screens.Edit /// Creates a new . /// /// The to track the s of. - /// The skin to track the inline skin configuration of. - public EditorChangeHandler(EditorBeatmap editorBeatmap, IBeatmapSkin beatmapSkin) + public EditorChangeHandler(EditorBeatmap editorBeatmap) { this.editorBeatmap = editorBeatmap; @@ -47,8 +44,6 @@ namespace osu.Game.Screens.Edit patcher = new LegacyEditorBeatmapPatcher(editorBeatmap); - this.beatmapSkin = beatmapSkin; - // Initial state. SaveState(); } @@ -90,7 +85,7 @@ namespace osu.Game.Screens.Edit using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) - new LegacyBeatmapEncoder(editorBeatmap, beatmapSkin).Encode(sw); + new LegacyBeatmapEncoder(editorBeatmap, editorBeatmap.BeatmapSkin).Encode(sw); savedStates.Add(stream.ToArray()); } From 07f6a6817961c0426baacb14507df4d1e4937451 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Sun, 30 Aug 2020 21:13:06 +0200 Subject: [PATCH 26/37] Update LegacyBeatmapEncoderTest.cs --- .../Formats/LegacyBeatmapEncoderTest.cs | 65 +++++++++++++++---- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index dc91af72e8..a8a3f266fc 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Beatmaps; @@ -61,24 +63,59 @@ namespace osu.Game.Tests.Beatmaps.Formats { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - beatmap.BeatmapInfo.Path = name; - beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo + using (var rs = new MemoryBeatmapResourceStore(stream, name)) { - Files = new List - { - new BeatmapSetFileInfo - { - Filename = name, - FileInfo = new osu.Game.IO.FileInfo { Hash = name } - } - }, - }; - - var beatmapSkin = new TestLegacySkin(beatmap, beatmaps_resource_store, name); - return (convert(beatmap), beatmapSkin); + var beatmapSkin = new TestLegacySkin(beatmap, rs, name); + return (convert(beatmap), beatmapSkin); + } } } + private class MemoryBeatmapResourceStore : IResourceStore + { + private readonly Stream beatmapData; + private readonly string beatmapName; + + public MemoryBeatmapResourceStore(Stream beatmapData, string beatmapName) + { + this.beatmapData = beatmapData; + this.beatmapName = beatmapName; + } + + public void Dispose() => beatmapData.Dispose(); + + public byte[] Get(string name) + { + if (name != beatmapName) + return null; + + byte[] buffer = new byte[beatmapData.Length]; + beatmapData.Read(buffer, 0, buffer.Length); + return buffer; + } + + public async Task GetAsync(string name) + { + if (name != beatmapName) + return null; + + byte[] buffer = new byte[beatmapData.Length]; + await beatmapData.ReadAsync(buffer.AsMemory()); + return buffer; + } + + public Stream GetStream(string name) + { + if (name != beatmapName) + return null; + + beatmapData.Seek(0, SeekOrigin.Begin); + return beatmapData; + } + + public IEnumerable GetAvailableResources() => beatmapName.Yield(); + } + private class TestLegacySkin : LegacySkin, IBeatmapSkin { public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) From eafa97af17a1ef203ccd4f25759401ccce169cc0 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:23:42 +0200 Subject: [PATCH 27/37] Revert changes done to SkinConfiguration and IHasCustomColours --- osu.Game/Beatmaps/Formats/IHasCustomColours.cs | 2 +- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs index 1ac5ca83cb..dba3a37545 100644 --- a/osu.Game/Beatmaps/Formats/IHasCustomColours.cs +++ b/osu.Game/Beatmaps/Formats/IHasCustomColours.cs @@ -8,6 +8,6 @@ namespace osu.Game.Beatmaps.Formats { public interface IHasCustomColours { - IDictionary CustomColours { get; } + Dictionary CustomColours { get; } } } diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index 7972cc7d06..65d5851455 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public IDictionary CustomColours { get; } = new SortedDictionary(); + public Dictionary CustomColours { get; set; } = new Dictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 18d970dd64..2857ad3824 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,9 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; -using System.Linq; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -12,7 +10,7 @@ namespace osu.Game.Skinning /// /// An empty skin configuration. /// - public class SkinConfiguration : IEquatable, IHasComboColours, IHasCustomColours + public class SkinConfiguration : IHasComboColours, IHasCustomColours { public readonly SkinInfo SkinInfo = new SkinInfo(); @@ -47,10 +45,8 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public IDictionary CustomColours { get; } = new SortedDictionary(); + public Dictionary CustomColours { get; set; } = new Dictionary(); public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); - - public bool Equals(SkinConfiguration other) => other != null && ConfigDictionary.SequenceEqual(other.ConfigDictionary) && ((ComboColours == null && other.ComboColours == null) || ComboColours.SequenceEqual(other.ComboColours)) && CustomColours.SequenceEqual(other.CustomColours); } } From 1484e78654743b8e68ead43811ed5735d681b13d Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:00 +0200 Subject: [PATCH 28/37] Update xmldoc --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 89a776dd31..f725d55970 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -195,7 +195,7 @@ namespace osu.Game.Beatmaps /// /// The to save the content against. The file referenced by will be replaced. /// The content to write. - /// The beatmap content to write, or null if not to be changed. + /// The beatmap content to write, null if to be omitted. public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); From fb37a14d577416754f17a569b9658989d7327c07 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:03 +0200 Subject: [PATCH 29/37] Update LegacyBeatmapEncoder.cs --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index cae6a43cd4..53ce1c831c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -25,6 +25,8 @@ namespace osu.Game.Beatmaps.Formats public const int LATEST_VERSION = 128; private readonly IBeatmap beatmap; + + [CanBeNull] private readonly IBeatmapSkin skin; /// @@ -64,7 +66,7 @@ namespace osu.Game.Beatmaps.Formats handleControlPoints(writer); writer.WriteLine(); - handleComboColours(writer); + handleColours(writer); writer.WriteLine(); handleHitObjects(writer); @@ -209,9 +211,9 @@ namespace osu.Game.Beatmaps.Formats } } - private void handleComboColours(TextWriter writer) + private void handleColours(TextWriter writer) { - var colours = skin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; + var colours = skin?.GetConfig>(GlobalSkinColours.ComboColours)?.Value; if (colours == null || colours.Count == 0) return; From a893aa8af86b5037dc1662adfe789112a61afea7 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:24:24 +0200 Subject: [PATCH 30/37] Cut down changes done to LegacyBeatmapEncoderTest --- .../Formats/LegacyBeatmapEncoderTest.cs | 71 +++++-------------- 1 file changed, 16 insertions(+), 55 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index a8a3f266fc..bcc5970a27 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -7,10 +7,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Audio.Track; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Game.Beatmaps; @@ -44,7 +42,19 @@ namespace osu.Game.Tests.Beatmaps.Formats sort(decodedAfterEncode); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); - Assert.IsTrue(decodedAfterEncode.beatmapSkin.Configuration.Equals(decoded.beatmapSkin.Configuration)); + Assert.IsTrue(areComboColoursEqual(decodedAfterEncode.beatmapSkin.Configuration, decoded.beatmapSkin.Configuration)); + } + + private bool areComboColoursEqual(IHasComboColours a, IHasComboColours b) + { + // equal to null, no need to SequenceEqual + if (a.ComboColours == null && b.ComboColours == null) + return true; + + if (a.ComboColours == null || b.ComboColours == null) + return false; + + return a.ComboColours.SequenceEqual(b.ComboColours); } private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) @@ -62,63 +72,14 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var reader = new LineBufferedReader(stream)) { var beatmap = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader); - - using (var rs = new MemoryBeatmapResourceStore(stream, name)) - { - var beatmapSkin = new TestLegacySkin(beatmap, rs, name); - return (convert(beatmap), beatmapSkin); - } + var beatmapSkin = new TestLegacySkin(beatmaps_resource_store, name); + return (convert(beatmap), beatmapSkin); } } - private class MemoryBeatmapResourceStore : IResourceStore - { - private readonly Stream beatmapData; - private readonly string beatmapName; - - public MemoryBeatmapResourceStore(Stream beatmapData, string beatmapName) - { - this.beatmapData = beatmapData; - this.beatmapName = beatmapName; - } - - public void Dispose() => beatmapData.Dispose(); - - public byte[] Get(string name) - { - if (name != beatmapName) - return null; - - byte[] buffer = new byte[beatmapData.Length]; - beatmapData.Read(buffer, 0, buffer.Length); - return buffer; - } - - public async Task GetAsync(string name) - { - if (name != beatmapName) - return null; - - byte[] buffer = new byte[beatmapData.Length]; - await beatmapData.ReadAsync(buffer.AsMemory()); - return buffer; - } - - public Stream GetStream(string name) - { - if (name != beatmapName) - return null; - - beatmapData.Seek(0, SeekOrigin.Begin); - return beatmapData; - } - - public IEnumerable GetAvailableResources() => beatmapName.Yield(); - } - private class TestLegacySkin : LegacySkin, IBeatmapSkin { - public TestLegacySkin(Beatmap beatmap, IResourceStore storage, string fileName) + public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) { } From a290f7eeec4ecefb46dc4288eb98f94c909f492b Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:34:18 +0200 Subject: [PATCH 31/37] Revert left-over type change in SkinConfiguration --- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 2857ad3824..a55870aa6d 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -47,6 +47,6 @@ namespace osu.Game.Skinning public Dictionary CustomColours { get; set; } = new Dictionary(); - public readonly SortedDictionary ConfigDictionary = new SortedDictionary(); + public readonly Dictionary ConfigDictionary = new Dictionary(); } } From 3cc169c933f2e4518fb9756d7905641d4fcf4167 Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Mon, 31 Aug 2020 17:48:36 +0200 Subject: [PATCH 32/37] Remove set from properties in SkinConfiguration classes I don't get why this wasn't resolved in the first place when this file was originally written. *sigh* --- osu.Game/Skinning/LegacyManiaSkinConfiguration.cs | 2 +- osu.Game/Skinning/SkinConfiguration.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs index 65d5851455..35a6140cbc 100644 --- a/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs +++ b/osu.Game/Skinning/LegacyManiaSkinConfiguration.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning public readonly int Keys; - public Dictionary CustomColours { get; set; } = new Dictionary(); + public Dictionary CustomColours { get; } = new Dictionary(); public Dictionary ImageLookups = new Dictionary(); diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a55870aa6d..25a924c929 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -45,7 +45,7 @@ namespace osu.Game.Skinning public void AddComboColours(params Color4[] colours) => comboColours.AddRange(colours); - public Dictionary CustomColours { get; set; } = new Dictionary(); + public Dictionary CustomColours { get; } = new Dictionary(); public readonly Dictionary ConfigDictionary = new Dictionary(); } From c2ade44656c3ea7d397d39652c77a70056d8fe1c Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Tue, 1 Sep 2020 17:58:06 +0200 Subject: [PATCH 33/37] Change types back --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 6 +++--- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 ++-- osu.Game/Screens/Edit/EditorBeatmap.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index bcc5970a27..613db79242 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Beatmaps.Formats return a.ComboColours.SequenceEqual(b.ComboColours); } - private void sort((IBeatmap beatmap, IBeatmapSkin beatmapSkin) tuple) + private void sort((IBeatmap beatmap, ISkin beatmapSkin) tuple) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. foreach (var g in tuple.beatmap.ControlPointInfo.Groups) @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private class TestLegacySkin : LegacySkin, IBeatmapSkin + private class TestLegacySkin : LegacySkin, ISkin { public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private Stream encodeToLegacy((IBeatmap beatmap, IBeatmapSkin beatmapSkin) fullBeatmap) + private Stream encodeToLegacy((IBeatmap beatmap, ISkin beatmapSkin) fullBeatmap) { var (beatmap, beatmapSkin) = fullBeatmap; var stream = new MemoryStream(); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f725d55970..a96af68714 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -196,7 +196,7 @@ namespace osu.Game.Beatmaps /// The to save the content against. The file referenced by will be replaced. /// The content to write. /// The beatmap content to write, null if to be omitted. - public void Save(BeatmapInfo info, IBeatmap beatmapContent, IBeatmapSkin beatmapSkin = null) + public void Save(BeatmapInfo info, IBeatmap beatmapContent, ISkin beatmapSkin = null) { var setInfo = QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == info.ID)); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 53ce1c831c..80a4d6dea4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -27,14 +27,14 @@ namespace osu.Game.Beatmaps.Formats private readonly IBeatmap beatmap; [CanBeNull] - private readonly IBeatmapSkin skin; + private readonly ISkin skin; /// /// Creates a new . /// /// The beatmap to encode. /// The beatmap's skin, used for encoding combo colours. - public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] IBeatmapSkin skin) + public LegacyBeatmapEncoder(IBeatmap beatmap, [CanBeNull] ISkin skin) { this.beatmap = beatmap; this.skin = skin; diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index a314d50e60..061009e519 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; - public readonly IBeatmapSkin BeatmapSkin; + public readonly ISkin BeatmapSkin; [Resolved] private BindableBeatDivisor beatDivisor { get; set; } @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap, IBeatmapSkin beatmapSkin = null) + public EditorBeatmap(IBeatmap playableBeatmap, ISkin beatmapSkin = null) { PlayableBeatmap = playableBeatmap; BeatmapSkin = beatmapSkin; From 2a7259f7aa76d1dac116af9b6d0f016ab15db2bb Mon Sep 17 00:00:00 2001 From: Craftplacer Date: Tue, 1 Sep 2020 18:15:46 +0200 Subject: [PATCH 34/37] Update LegacyBeatmapEncoderTest.cs --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 613db79242..6e103af3f0 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Beatmaps.Formats } } - private class TestLegacySkin : LegacySkin, ISkin + private class TestLegacySkin : LegacySkin { public TestLegacySkin(IResourceStore storage, string fileName) : base(new SkinInfo { Name = "Test Skin", Creator = "Craftplacer" }, storage, null, fileName) From 2b16e2535304263507f338bad1591e4d25cf70e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 6 Sep 2020 18:44:41 +0200 Subject: [PATCH 35/37] Revert unnecessary passing down of tuple in test --- .../Beatmaps/Formats/LegacyBeatmapEncoderTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs index 6e103af3f0..17d910036f 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapEncoderTest.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Beatmaps.Formats var decoded = decodeFromLegacy(beatmaps_resource_store.GetStream(name), name); var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded), name); - sort(decoded); - sort(decodedAfterEncode); + sort(decoded.beatmap); + sort(decodedAfterEncode.beatmap); Assert.That(decodedAfterEncode.beatmap.Serialize(), Is.EqualTo(decoded.beatmap.Serialize())); Assert.IsTrue(areComboColoursEqual(decodedAfterEncode.beatmapSkin.Configuration, decoded.beatmapSkin.Configuration)); @@ -57,10 +57,10 @@ namespace osu.Game.Tests.Beatmaps.Formats return a.ComboColours.SequenceEqual(b.ComboColours); } - private void sort((IBeatmap beatmap, ISkin beatmapSkin) tuple) + private void sort(IBeatmap beatmap) { // Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points. - foreach (var g in tuple.beatmap.ControlPointInfo.Groups) + foreach (var g in beatmap.ControlPointInfo.Groups) { ArrayList.Adapter((IList)g.ControlPoints).Sort( Comparer.Create((c1, c2) => string.Compare(c1.GetType().ToString(), c2.GetType().ToString(), StringComparison.Ordinal))); From b4b9c71f00eab44bb189a3d1936b71edc6219c03 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 6 Sep 2020 10:13:06 -0700 Subject: [PATCH 36/37] Make all toolbar tooltips lowercase --- osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs | 2 +- osu.Game/Overlays/News/NewsHeader.cs | 2 +- osu.Game/Overlays/NotificationOverlay.cs | 4 ++-- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs | 4 ++-- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index b7f511271c..6a9a71210a 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.BeatmapListing public BeatmapListingTitle() { Title = "beatmap listing"; - Description = "Browse for new beatmaps"; + Description = "browse for new beatmaps"; IconTexture = "Icons/Hexacons/beatmap"; } } diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index bdc59297bb..f4be4328e7 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeaderTitle() { Title = "changelog"; - Description = "Track recent dev updates in the osu! ecosystem"; + Description = "track recent dev updates in the osu! ecosystem"; IconTexture = "Icons/Hexacons/devtools"; } } diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index a964d84c4f..36bf589877 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Dashboard public DashboardTitle() { Title = "dashboard"; - Description = "View your friends and other information"; + Description = "view your friends and other information"; IconTexture = "Icons/Hexacons/social"; } } diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index 38ac519387..63174128e7 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -57,7 +57,7 @@ namespace osu.Game.Overlays.News public NewsHeaderTitle() { Title = "news"; - Description = "Get up-to-date on community happenings"; + Description = "get up-to-date on community happenings"; IconTexture = "Icons/Hexacons/news"; } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index b7d916c48f..b5714fbcae 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/notification"; - public string Title => "Notifications"; - public string Description => "Waiting for 'ya"; + public string Title => "notifications"; + public string Description => "waiting for 'ya"; private const float width = 320; diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 7039ab8214..92e22f5873 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Rankings public RankingsTitle() { Title = "ranking"; - Description = "Find out who's the best right now"; + Description = "find out who's the best right now"; IconTexture = "Icons/Hexacons/rankings"; } } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 0532a031f3..e1bcdbbaf0 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/settings"; public string Title => "settings"; - public string Description => "Change the way osu! behaves"; + public string Description => "change the way osu! behaves"; protected override IEnumerable CreateSections() => new SettingsSection[] { diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 6b2c24c0f3..76fbd40d66 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -17,8 +17,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = "Home"; - TooltipSub = "Return to the main menu"; + TooltipMain = "home"; + TooltipSub = "return to the main menu"; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 754b679599..564fd65719 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = $"Play some {rInstance.Description}"; + ruleset.TooltipSub = $"play some {rInstance.Description}"; ruleset.SetIcon(rInstance.CreateIcon()); } From 8f8f907fc7c3dda37646e8e6a8eca762ca47d32a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Sep 2020 13:27:28 +0900 Subject: [PATCH 37/37] Fix missed string --- osu.Game/Overlays/NowPlayingOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index d1df1fa936..55adf02a45 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays { public string IconTexture => "Icons/Hexacons/music"; public string Title => "now playing"; - public string Description => "Manage the currently playing track"; + public string Description => "manage the currently playing track"; private const float player_height = 130; private const float transition_length = 800;