1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 01:33:10 +08:00

Merge pull request #25775 from peppy/more-import-lenience

Allow new common cases when a user is locating a stable osu! install directory for import
This commit is contained in:
Dean Herbert 2023-12-17 12:12:06 +09:00 committed by GitHub
commit 7573e316bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 18 deletions

View File

@ -3,6 +3,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework;
@ -54,6 +57,49 @@ namespace osu.Game.Database
public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, gameHost as DesktopGameHost);
/// <summary>
/// Checks whether a valid location to run a stable import from can be determined starting from the supplied <paramref name="directory"/>.
/// </summary>
/// <param name="directory">The directory to check for stable import eligibility.</param>
/// <param name="stableRoot">
/// If the return value is <see langword="true"/>,
/// this parameter will contain the <see cref="DirectoryInfo"/> to use as the root directory for importing.
/// </param>
public bool IsUsableForStableImport(DirectoryInfo? directory, [NotNullWhen(true)] out DirectoryInfo? stableRoot)
{
if (directory == null)
{
stableRoot = null;
return false;
}
// A full stable installation will have a configuration file present.
// This is the best case scenario, as it may contain a custom beatmap directory we need to traverse to.
if (directory.GetFiles(@"osu!.*.cfg").Any())
{
stableRoot = directory;
return true;
}
// The user may only have their songs or skins folders left.
// We still want to allow them to import based on this.
if (directory.GetDirectories(@"Songs").Any() || directory.GetDirectories(@"Skins").Any())
{
stableRoot = directory;
return true;
}
// The user may have traversed *inside* their songs or skins folders.
if (directory.Parent != null && (directory.Name == @"Songs" || directory.Name == @"Skins"))
{
stableRoot = directory.Parent;
return true;
}
stableRoot = null;
return false;
}
public bool CheckSongsFolderHardLinkAvailability()
{
var stableStorage = GetCurrentStableStorage();

View File

@ -244,6 +244,8 @@ namespace osu.Game.Overlays.FirstRunSetup
[Resolved(canBeNull: true)] // Can't really be null but required to handle potential of disposal before DI completes.
private OsuGameBase? game { get; set; }
private bool changingDirectory;
protected override void LoadComplete()
{
base.LoadComplete();
@ -259,24 +261,37 @@ namespace osu.Game.Overlays.FirstRunSetup
private void onDirectorySelected(ValueChangedEvent<DirectoryInfo?> directory)
{
if (directory.NewValue == null)
{
Current.Value = string.Empty;
if (changingDirectory)
return;
try
{
changingDirectory = true;
if (directory.NewValue == null)
{
Current.Value = string.Empty;
return;
}
// DirectorySelectors can trigger a noop value changed, but `DirectoryInfo` equality doesn't catch this.
if (directory.OldValue?.FullName == directory.NewValue.FullName)
return;
if (legacyImportManager.IsUsableForStableImport(directory.NewValue, out var stableRoot))
{
this.HidePopover();
string path = stableRoot.FullName;
legacyImportManager.UpdateStorage(path);
Current.Value = path;
currentDirectory.Value = stableRoot;
}
}
// DirectorySelectors can trigger a noop value changed, but `DirectoryInfo` equality doesn't catch this.
if (directory.OldValue?.FullName == directory.NewValue.FullName)
return;
if (directory.NewValue?.GetFiles(@"osu!.*.cfg").Any() ?? false)
finally
{
this.HidePopover();
string path = directory.NewValue.FullName;
legacyImportManager.UpdateStorage(path);
Current.Value = path;
changingDirectory = false;
}
}

View File

@ -1,11 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Framework.Screens;
using osu.Game.Database;
namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
@ -13,9 +15,12 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
private readonly TaskCompletionSource<string> taskCompletionSource;
[Resolved]
private LegacyImportManager legacyImportManager { get; set; } = null!;
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
protected override bool IsValidDirectory(DirectoryInfo? info) => info?.GetFiles("osu!.*.cfg").Any() ?? false;
protected override bool IsValidDirectory(DirectoryInfo? info) => legacyImportManager.IsUsableForStableImport(info, out _);
public override LocalisableString HeaderText => "Please select your osu!stable install location";
@ -26,7 +31,10 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
protected override void OnSelection(DirectoryInfo directory)
{
taskCompletionSource.TrySetResult(directory.FullName);
if (!legacyImportManager.IsUsableForStableImport(directory, out var stableRoot))
throw new InvalidOperationException($@"{nameof(OnSelection)} was called on an invalid directory. This should never happen.");
taskCompletionSource.TrySetResult(stableRoot.FullName);
this.Exit();
}