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:
commit
a8acbbe69c
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
96
osu.Game/Database/StableImportManager.cs
Normal file
96
osu.Game/Database/StableImportManager.cs
Normal 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
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user