1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-19 01:17:19 +08:00

Merge pull request #12779 from Game4all/import-from-stable-select-location

Add ability to manually locate a stable location when importing from stable
This commit is contained in:
Dean Herbert 2021-05-21 18:17:30 +09:00 committed by GitHub
commit a8acbbe69c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 247 additions and 102 deletions

View File

@ -11,8 +11,8 @@ using osu.Game.Overlays;
using osu.Game.Screens;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Play;
using osu.Game.Screens.Select;
using osuTK.Input;
using static osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation;
namespace osu.Game.Tests.Visual.Navigation
{
@ -37,17 +37,17 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestPerformAtSongSelect()
{
PushAndConfirm(() => new PlaySongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
AddStep("perform immediately", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(PlaySongSelect) }));
AddStep("perform immediately", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(TestPlaySongSelect) }));
AddAssert("did perform", () => actionPerformed);
AddAssert("screen didn't change", () => Game.ScreenStack.CurrentScreen is PlaySongSelect);
AddAssert("screen didn't change", () => Game.ScreenStack.CurrentScreen is TestPlaySongSelect);
}
[Test]
public void TestPerformAtMenuFromSongSelect()
{
PushAndConfirm(() => new PlaySongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true));
AddUntilStep("returned to menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
@ -57,18 +57,18 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestPerformAtSongSelectFromPlayerLoader()
{
PushAndConfirm(() => new PlaySongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
PushAndConfirm(() => new PlayerLoader(() => new SoloPlayer()));
AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(PlaySongSelect) }));
AddUntilStep("returned to song select", () => Game.ScreenStack.CurrentScreen is PlaySongSelect);
AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(TestPlaySongSelect) }));
AddUntilStep("returned to song select", () => Game.ScreenStack.CurrentScreen is TestPlaySongSelect);
AddAssert("did perform", () => actionPerformed);
}
[Test]
public void TestPerformAtMenuFromPlayerLoader()
{
PushAndConfirm(() => new PlaySongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
PushAndConfirm(() => new PlayerLoader(() => new SoloPlayer()));
AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true));

View File

@ -34,9 +34,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestExitSongSelectWithEscape()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
pushEscape();
@ -51,9 +51,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestOpenModSelectOverlayUsingAction()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show mods overlay", () => InputManager.Key(Key.F1));
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
}
@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Navigation
{
Player player = null;
PushAndConfirm(() => new TestSongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
@ -89,7 +89,7 @@ namespace osu.Game.Tests.Visual.Navigation
WorkingBeatmap beatmap() => Game.Beatmap.Value;
PushAndConfirm(() => new TestSongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.Navigation
WorkingBeatmap beatmap() => Game.Beatmap.Value;
PushAndConfirm(() => new TestSongSelect());
PushAndConfirm(() => new TestPlaySongSelect());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
@ -139,9 +139,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestMenuMakesMusic()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for no track", () => Game.MusicController.CurrentTrack.IsDummyDevice);
@ -153,9 +153,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestExitSongSelectWithClick()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition));
@ -213,9 +213,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestModSelectInput()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
@ -234,9 +234,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestBeatmapOptionsInput()
{
TestSongSelect songSelect = null;
TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestSongSelect());
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show options overlay", () => songSelect.BeatmapOptionsOverlay.Show());
@ -312,11 +312,13 @@ namespace osu.Game.Tests.Visual.Navigation
ConfirmAtMainMenu();
}
private class TestSongSelect : PlaySongSelect
public class TestPlaySongSelect : PlaySongSelect
{
public ModSelectOverlay ModSelectOverlay => ModSelect;
public BeatmapOptionsOverlay BeatmapOptionsOverlay => BeatmapOptions;
protected override bool DisplayStableImportPrompt => false;
}
}
}

View File

@ -8,13 +8,13 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.IO;
using osu.Game.IO.Legacy;
using osu.Game.Overlays.Notifications;
@ -38,8 +38,6 @@ namespace osu.Game.Collections
public readonly BindableList<BeatmapCollection> Collections = new BindableList<BeatmapCollection>();
public bool SupportsImportFromStable => RuntimeInfo.IsDesktop;
[Resolved]
private GameHost host { get; set; }
@ -96,25 +94,12 @@ namespace osu.Game.Collections
/// </summary>
public Action<Notification> PostNotification { protected get; set; }
/// <summary>
/// Set a storage with access to an osu-stable install for import purposes.
/// </summary>
public Func<Storage> GetStableStorage { private get; set; }
/// <summary>
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
/// </summary>
public Task ImportFromStableAsync()
public Task ImportFromStableAsync(StableStorage stableStorage)
{
var stable = GetStableStorage?.Invoke();
if (stable == null)
{
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
return Task.CompletedTask;
}
if (!stable.Exists(database_name))
if (!stableStorage.Exists(database_name))
{
// This handles situations like when the user does not have a collections.db file
Logger.Log($"No {database_name} available in osu!stable installation", LoggingTarget.Information, LogLevel.Error);
@ -123,7 +108,7 @@ namespace osu.Game.Collections
return Task.Run(async () =>
{
using (var stream = stable.GetStream(database_name))
using (var stream = stableStorage.GetStream(database_name))
await Import(stream).ConfigureAwait(false);
});
}

View File

@ -10,7 +10,6 @@ using System.Threading.Tasks;
using Humanizer;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using osu.Framework;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.IEnumerableExtensions;
@ -81,8 +80,6 @@ namespace osu.Game.Database
public virtual IEnumerable<string> HandledExtensions => new[] { ".zip" };
public virtual bool SupportsImportFromStable => RuntimeInfo.IsDesktop;
protected readonly FileStore Files;
protected readonly IDatabaseContextFactory ContextFactory;
@ -669,16 +666,6 @@ namespace osu.Game.Database
#region osu-stable import
/// <summary>
/// Set a storage with access to an osu-stable install for import purposes.
/// </summary>
public Func<StableStorage> GetStableStorage { private get; set; }
/// <summary>
/// Denotes whether an osu-stable installation is present to perform automated imports from.
/// </summary>
public bool StableInstallationAvailable => GetStableStorage?.Invoke() != null;
/// <summary>
/// The relative path from osu-stable's data directory to import items from.
/// </summary>
@ -700,22 +687,16 @@ namespace osu.Game.Database
/// <summary>
/// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future.
/// </summary>
public Task ImportFromStableAsync()
public Task ImportFromStableAsync(StableStorage stableStorage)
{
var stableStorage = GetStableStorage?.Invoke();
if (stableStorage == null)
{
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
return Task.CompletedTask;
}
var storage = PrepareStableStorage(stableStorage);
// Handle situations like when the user does not have a Skins folder.
if (!storage.ExistsDirectory(ImportFromStablePath))
{
// This handles situations like when the user does not have a Skins folder
Logger.Log($"No {ImportFromStablePath} folder available in osu!stable installation", LoggingTarget.Information, LogLevel.Error);
string fullPath = storage.GetFullPath(ImportFromStablePath);
Logger.Log($"Folder \"{fullPath}\" not available in the target osu!stable installation to import {HumanisedModelName}s.", LoggingTarget.Information, LogLevel.Error);
return Task.CompletedTask;
}

View File

@ -0,0 +1,96 @@
// 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.Collections.Generic;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.IO;
using osu.Game.Overlays;
using osu.Game.Overlays.Settings.Sections.Maintenance;
using osu.Game.Scoring;
using osu.Game.Skinning;
namespace osu.Game.Database
{
public class StableImportManager : Component
{
[Resolved]
private SkinManager skins { get; set; }
[Resolved]
private BeatmapManager beatmaps { get; set; }
[Resolved]
private ScoreManager scores { get; set; }
[Resolved]
private CollectionManager collections { get; set; }
[Resolved]
private OsuGame game { get; set; }
[Resolved]
private DialogOverlay dialogOverlay { get; set; }
[Resolved(CanBeNull = true)]
private DesktopGameHost desktopGameHost { get; set; }
private StableStorage cachedStorage;
public bool SupportsImportFromStable => RuntimeInfo.IsDesktop;
public async Task ImportFromStableAsync(StableContent content)
{
var stableStorage = await getStableStorage().ConfigureAwait(false);
var importTasks = new List<Task>();
Task beatmapImportTask = Task.CompletedTask;
if (content.HasFlagFast(StableContent.Beatmaps))
importTasks.Add(beatmapImportTask = beatmaps.ImportFromStableAsync(stableStorage));
if (content.HasFlagFast(StableContent.Skins))
importTasks.Add(skins.ImportFromStableAsync(stableStorage));
if (content.HasFlagFast(StableContent.Collections))
importTasks.Add(beatmapImportTask.ContinueWith(_ => collections.ImportFromStableAsync(stableStorage), TaskContinuationOptions.OnlyOnRanToCompletion));
if (content.HasFlagFast(StableContent.Scores))
importTasks.Add(beatmapImportTask.ContinueWith(_ => scores.ImportFromStableAsync(stableStorage), TaskContinuationOptions.OnlyOnRanToCompletion));
await Task.WhenAll(importTasks.ToArray()).ConfigureAwait(false);
}
private async Task<StableStorage> getStableStorage()
{
if (cachedStorage != null)
return cachedStorage;
var stableStorage = game.GetStorageForStableInstall();
if (stableStorage != null)
return cachedStorage = stableStorage;
var taskCompletionSource = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
Schedule(() => dialogOverlay.Push(new StableDirectoryLocationDialog(taskCompletionSource)));
var stablePath = await taskCompletionSource.Task.ConfigureAwait(false);
return cachedStorage = new StableStorage(stablePath, desktopGameHost);
}
}
[Flags]
public enum StableContent
{
Beatmaps = 1 << 0,
Scores = 1 << 1,
Skins = 1 << 2,
Collections = 1 << 3,
All = Beatmaps | Scores | Skins | Collections
}
}

View File

@ -100,6 +100,9 @@ namespace osu.Game
[Cached]
private readonly DifficultyRecommender difficultyRecommender = new DifficultyRecommender();
[Cached]
private readonly StableImportManager stableImportManager = new StableImportManager();
[Cached]
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
@ -566,14 +569,11 @@ namespace osu.Game
// todo: all archive managers should be able to be looped here.
SkinManager.PostNotification = n => notifications.Post(n);
SkinManager.GetStableStorage = GetStorageForStableInstall;
BeatmapManager.PostNotification = n => notifications.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall;
BeatmapManager.PresentImport = items => PresentBeatmap(items.First());
ScoreManager.PostNotification = n => notifications.Post(n);
ScoreManager.GetStableStorage = GetStorageForStableInstall;
ScoreManager.PresentImport = items => PresentScore(items.First());
// make config aware of how to lookup skins for on-screen display purposes.
@ -690,10 +690,10 @@ namespace osu.Game
loadComponentSingleFile(new CollectionManager(Storage)
{
PostNotification = n => notifications.Post(n),
GetStableStorage = GetStorageForStableInstall
}, Add, true);
loadComponentSingleFile(difficultyRecommender, Add);
loadComponentSingleFile(stableImportManager, Add);
loadComponentSingleFile(screenshotManager, Add);

View File

@ -11,9 +11,9 @@ using osuTK;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Localisation;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Screens;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
@ -69,20 +69,24 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
RelativeSizeAxes = Axes.Both,
RowDimensions = new[]
{
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
new Dimension(GridSizeMode.Relative, 0.8f),
new Dimension(),
new Dimension(GridSizeMode.AutoSize),
},
Content = new[]
{
new Drawable[]
{
new OsuSpriteText
new OsuTextFlowContainer(cp =>
{
Text = HeaderText,
Font = OsuFont.Default.With(size: 40),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
cp.Font = OsuFont.Default.With(size: 24);
})
{
Text = HeaderText.ToString(),
TextAnchor = Anchor.TopCentre,
Margin = new MarginPadding(10),
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
}
},
new Drawable[]
@ -99,6 +103,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Width = 300,
Margin = new MarginPadding(10),
Text = "Select directory",
Action = () => OnSelection(directorySelector.CurrentPath.Value)
},

View File

@ -8,6 +8,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
using osu.Game.Scoring;
using osu.Game.Skinning;
@ -29,9 +30,9 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
private TriangleButton undeleteButton;
[BackgroundDependencyLoader(permitNulls: true)]
private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, [CanBeNull] CollectionManager collectionManager, DialogOverlay dialogOverlay)
private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, [CanBeNull] CollectionManager collectionManager, [CanBeNull] StableImportManager stableImportManager, DialogOverlay dialogOverlay)
{
if (beatmaps.SupportsImportFromStable)
if (stableImportManager?.SupportsImportFromStable == true)
{
Add(importBeatmapsButton = new SettingsButton
{
@ -39,7 +40,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Action = () =>
{
importBeatmapsButton.Enabled.Value = false;
beatmaps.ImportFromStableAsync().ContinueWith(t => Schedule(() => importBeatmapsButton.Enabled.Value = true));
stableImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(t => Schedule(() => importBeatmapsButton.Enabled.Value = true));
}
});
}
@ -57,7 +58,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}
});
if (scores.SupportsImportFromStable)
if (stableImportManager?.SupportsImportFromStable == true)
{
Add(importScoresButton = new SettingsButton
{
@ -65,7 +66,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Action = () =>
{
importScoresButton.Enabled.Value = false;
scores.ImportFromStableAsync().ContinueWith(t => Schedule(() => importScoresButton.Enabled.Value = true));
stableImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(t => Schedule(() => importScoresButton.Enabled.Value = true));
}
});
}
@ -83,7 +84,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
}
});
if (skins.SupportsImportFromStable)
if (stableImportManager?.SupportsImportFromStable == true)
{
Add(importSkinsButton = new SettingsButton
{
@ -91,7 +92,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Action = () =>
{
importSkinsButton.Enabled.Value = false;
skins.ImportFromStableAsync().ContinueWith(t => Schedule(() => importSkinsButton.Enabled.Value = true));
stableImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(t => Schedule(() => importSkinsButton.Enabled.Value = true));
}
});
}
@ -111,7 +112,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
if (collectionManager != null)
{
if (collectionManager.SupportsImportFromStable)
if (stableImportManager?.SupportsImportFromStable == true)
{
Add(importCollectionsButton = new SettingsButton
{
@ -119,7 +120,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Action = () =>
{
importCollectionsButton.Enabled.Value = false;
collectionManager.ImportFromStableAsync().ContinueWith(t => Schedule(() => importCollectionsButton.Enabled.Value = true));
stableImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(t => Schedule(() => importCollectionsButton.Enabled.Value = true));
}
});
}

View File

@ -0,0 +1,38 @@
// 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.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Screens;
using osu.Game.Overlays.Dialog;
namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
public class StableDirectoryLocationDialog : PopupDialog
{
[Resolved]
private OsuGame game { get; set; }
public StableDirectoryLocationDialog(TaskCompletionSource<string> taskCompletionSource)
{
HeaderText = "Failed to automatically locate an osu!stable installation.";
BodyText = "An existing install could not be located. If you know where it is, you can help locate it.";
Icon = FontAwesome.Solid.QuestionCircle;
Buttons = new PopupDialogButton[]
{
new PopupDialogOkButton
{
Text = "Sure! I know where it is located!",
Action = () => Schedule(() => game.PerformFromScreen(screen => screen.Push(new StableDirectorySelectScreen(taskCompletionSource))))
},
new PopupDialogCancelButton
{
Text = "Actually I don't have osu!stable installed.",
Action = () => taskCompletionSource.TrySetCanceled()
}
};
}
}
}

View File

@ -0,0 +1,39 @@
// 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.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Localisation;
using osu.Framework.Screens;
namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
public class StableDirectorySelectScreen : DirectorySelectScreen
{
private readonly TaskCompletionSource<string> taskCompletionSource;
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
protected override bool IsValidDirectory(DirectoryInfo info) => info?.GetFiles("osu!.*.cfg").Any() ?? false;
public override LocalisableString HeaderText => "Please select your osu!stable install location";
public StableDirectorySelectScreen(TaskCompletionSource<string> taskCompletionSource)
{
this.taskCompletionSource = taskCompletionSource;
}
protected override void OnSelection(DirectoryInfo directory)
{
taskCompletionSource.TrySetResult(directory.FullName);
this.Exit();
}
public override bool OnExiting(IScreen next)
{
taskCompletionSource.TrySetCanceled();
return base.OnExiting(next);
}
}
}

View File

@ -12,7 +12,7 @@ namespace osu.Game.Screens.Select
public ImportFromStablePopup(Action importFromStable)
{
HeaderText = @"You have no beatmaps!";
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins, collections and scores?\nThis will create a second copy of all files on disk.";
BodyText = "Would you like to import your beatmaps, skins, collections and scores from an existing osu!stable installation?\nThis will create a second copy of all files on disk.";
Icon = FontAwesome.Solid.Plane;

View File

@ -22,7 +22,6 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Menu;
using osu.Game.Screens.Select.Options;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
@ -35,9 +34,9 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Collections;
using osu.Game.Graphics.UserInterface;
using osu.Game.Scoring;
using System.Diagnostics;
using osu.Game.Screens.Play;
using osu.Game.Database;
namespace osu.Game.Screens.Select
{
@ -52,6 +51,8 @@ namespace osu.Game.Screens.Select
protected virtual bool ShowFooter => true;
protected virtual bool DisplayStableImportPrompt => stableImportManager?.SupportsImportFromStable == true;
/// <summary>
/// Can be null if <see cref="ShowFooter"/> is false.
/// </summary>
@ -84,6 +85,9 @@ namespace osu.Game.Screens.Select
[Resolved]
private BeatmapManager beatmaps { get; set; }
[Resolved(CanBeNull = true)]
private StableImportManager stableImportManager { get; set; }
protected ModSelectOverlay ModSelect { get; private set; }
protected Sample SampleConfirm { get; private set; }
@ -101,7 +105,7 @@ namespace osu.Game.Screens.Select
private MusicController music { get; set; }
[BackgroundDependencyLoader(true)]
private void load(AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores, CollectionManager collections, ManageCollectionsDialog manageCollectionsDialog, DifficultyRecommender recommender)
private void load(AudioManager audio, DialogOverlay dialog, OsuColour colours, ManageCollectionsDialog manageCollectionsDialog, DifficultyRecommender recommender)
{
// initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter).
transferRulesetValue();
@ -282,18 +286,12 @@ namespace osu.Game.Screens.Select
{
Schedule(() =>
{
// if we have no beatmaps but osu-stable is found, let's prompt the user to import.
if (!beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.Minimal).Any() && beatmaps.StableInstallationAvailable)
// if we have no beatmaps, let's prompt the user to import from over a stable install if he has one.
if (!beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.Minimal).Any() && DisplayStableImportPrompt)
{
dialogOverlay.Push(new ImportFromStablePopup(() =>
{
Task.Run(beatmaps.ImportFromStableAsync)
.ContinueWith(_ =>
{
Task.Run(scores.ImportFromStableAsync);
Task.Run(collections.ImportFromStableAsync);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
Task.Run(skins.ImportFromStableAsync);
Task.Run(() => stableImportManager.ImportFromStableAsync(StableContent.All));
}));
}
});