diff --git a/osu.Android.props b/osu.Android.props
index f552aff2f2..9e0d31e7e5 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs
index ab2bc4649a..af3d9beb69 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs
@@ -56,6 +56,11 @@ namespace osu.Game.Tests.Visual.Editing
checkMutations();
+ // After placement these must be non-default as defaults are read-only.
+ AddAssert("Placed object has non-default control points", () =>
+ editorBeatmap.HitObjects[0].SampleControlPoint != SampleControlPoint.DEFAULT &&
+ editorBeatmap.HitObjects[0].DifficultyControlPoint != DifficultyControlPoint.DEFAULT);
+
AddStep("Save", () => InputManager.Keys(PlatformAction.Save));
checkMutations();
diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs
index 9c777d324b..f3ed2d735b 100644
--- a/osu.Game/Database/ArchiveModelManager.cs
+++ b/osu.Game/Database/ArchiveModelManager.cs
@@ -462,10 +462,12 @@ namespace osu.Game.Database
if (retrievedItem == null)
throw new ArgumentException(@"Specified model could not be found", nameof(item));
- using (var outputStream = exportStorage.GetStream($"{getValidFilename(item.ToString())}{HandledExtensions.First()}", FileAccess.Write, FileMode.Create))
- ExportModelTo(retrievedItem, outputStream);
+ string filename = $"{getValidFilename(item.ToString())}{HandledExtensions.First()}";
- exportStorage.OpenInNativeExplorer();
+ using (var stream = exportStorage.GetStream(filename, FileAccess.Write, FileMode.Create))
+ ExportModelTo(retrievedItem, stream);
+
+ exportStorage.PresentFileExternally(filename);
}
///
diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs
index 9cd403f409..e652f07239 100644
--- a/osu.Game/Graphics/ScreenshotManager.cs
+++ b/osu.Game/Graphics/ScreenshotManager.cs
@@ -109,40 +109,42 @@ namespace osu.Game.Graphics
if (Interlocked.Decrement(ref screenShotTasks) == 0 && cursorVisibility.Value == false)
cursorVisibility.Value = true;
- var fileName = getFileName();
- if (fileName == null) return;
+ string filename = getFilename();
- var stream = storage.GetStream(fileName, FileAccess.Write);
+ if (filename == null) return;
- switch (screenshotFormat.Value)
+ using (var stream = storage.GetStream(filename, FileAccess.Write))
{
- case ScreenshotFormat.Png:
- await image.SaveAsPngAsync(stream).ConfigureAwait(false);
- break;
+ switch (screenshotFormat.Value)
+ {
+ case ScreenshotFormat.Png:
+ await image.SaveAsPngAsync(stream).ConfigureAwait(false);
+ break;
- case ScreenshotFormat.Jpg:
- const int jpeg_quality = 92;
+ case ScreenshotFormat.Jpg:
+ const int jpeg_quality = 92;
- await image.SaveAsJpegAsync(stream, new JpegEncoder { Quality = jpeg_quality }).ConfigureAwait(false);
- break;
+ await image.SaveAsJpegAsync(stream, new JpegEncoder { Quality = jpeg_quality }).ConfigureAwait(false);
+ break;
- default:
- throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
+ default:
+ throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
+ }
}
notificationOverlay.Post(new SimpleNotification
{
- Text = $"{fileName} saved!",
+ Text = $"{filename} saved!",
Activated = () =>
{
- storage.OpenInNativeExplorer();
+ storage.PresentFileExternally(filename);
return true;
}
});
}
});
- private string getFileName()
+ private string getFilename()
{
var dt = DateTime.Now;
var fileExt = screenshotFormat.ToString().ToLowerInvariant();
diff --git a/osu.Game/IO/WrappedStorage.cs b/osu.Game/IO/WrappedStorage.cs
index b9ccc907d9..aadc4e760b 100644
--- a/osu.Game/IO/WrappedStorage.cs
+++ b/osu.Game/IO/WrappedStorage.cs
@@ -70,7 +70,9 @@ namespace osu.Game.IO
public override Stream GetStream(string path, FileAccess access = FileAccess.Read, FileMode mode = FileMode.OpenOrCreate) =>
UnderlyingStorage.GetStream(MutatePath(path), access, mode);
- public override void OpenPathInNativeExplorer(string path) => UnderlyingStorage.OpenPathInNativeExplorer(MutatePath(path));
+ public override void OpenFileExternally(string filename) => UnderlyingStorage.OpenFileExternally(MutatePath(filename));
+
+ public override void PresentFileExternally(string filename) => UnderlyingStorage.PresentFileExternally(MutatePath(filename));
public override Storage GetStorageForDirectory(string path)
{
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 2cbe05fecd..985451fd6f 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -913,13 +913,15 @@ namespace osu.Game
}
else if (recentLogCount == short_term_display_limit)
{
+ var logFile = $@"{entry.Target.ToString().ToLowerInvariant()}.log";
+
Schedule(() => Notifications.Post(new SimpleNotification
{
Icon = FontAwesome.Solid.EllipsisH,
Text = "Subsequent messages have been logged. Click to view log files.",
Activated = () =>
{
- Storage.GetStorageForDirectory("logs").OpenInNativeExplorer();
+ Storage.GetStorageForDirectory(@"logs").PresentFileExternally(logFile);
return true;
}
}));
diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
index aa37748653..6bcb5ef715 100644
--- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
Add(new SettingsButton
{
Text = GeneralSettingsStrings.OpenOsuFolder,
- Action = storage.OpenInNativeExplorer,
+ Action = storage.PresentExternally,
});
Add(new SettingsButton
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index 035ebe10cb..a80b3d0fa5 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -119,6 +119,8 @@ namespace osu.Game.Rulesets.Objects
DifficultyControlPoint = (DifficultyControlPoint)legacyInfo.DifficultyPointAt(StartTime).DeepClone();
DifficultyControlPoint.Time = StartTime;
}
+ else if (DifficultyControlPoint == DifficultyControlPoint.DEFAULT)
+ DifficultyControlPoint = new DifficultyControlPoint();
ApplyDefaultsToSelf(controlPointInfo, difficulty);
@@ -128,6 +130,8 @@ namespace osu.Game.Rulesets.Objects
SampleControlPoint = (SampleControlPoint)legacyInfo.SamplePointAt(this.GetEndTime() + control_point_leniency).DeepClone();
SampleControlPoint.Time = this.GetEndTime() + control_point_leniency;
}
+ else if (SampleControlPoint == SampleControlPoint.DEFAULT)
+ SampleControlPoint = new SampleControlPoint();
nestedHitObjects.Clear();
diff --git a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
index 663746bfca..052fc7c775 100644
--- a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
+++ b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
@@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Objects
public static void Reverse(this SliderPath sliderPath, out Vector2 positionalOffset)
{
var points = sliderPath.ControlPoints.ToArray();
- positionalOffset = points.Last().Position;
+ positionalOffset = sliderPath.PositionAt(1);
sliderPath.ControlPoints.Clear();
@@ -32,7 +32,10 @@ namespace osu.Game.Rulesets.Objects
// propagate types forwards to last null type
if (i == points.Length - 1)
+ {
p.Type = lastType;
+ p.Position = Vector2.Zero;
+ }
else if (p.Type != null)
(p.Type, lastType) = (lastType, p.Type);
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs
index ff24035d0e..0e73f65f8b 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs
@@ -10,7 +10,6 @@ using osu.Game.Input.Bindings;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Screens.Play;
-using osuTK.Input;
namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 32d6eeab29..a9555b555e 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -36,7 +36,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 92abab036a..1669573c26 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -70,7 +70,7 @@
-
+
@@ -93,7 +93,7 @@
-
+