mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 21:52:55 +08:00
Merge pull request #11603 from Game4all/handle-stable-imports-custom-songs-folder
Handle beatmap import from a stable installation with a custom Songs directory
This commit is contained in:
commit
a080a9bdbc
@ -18,6 +18,7 @@ using osu.Framework.Screens;
|
|||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osu.Game.Updater;
|
using osu.Game.Updater;
|
||||||
using osu.Desktop.Windows;
|
using osu.Desktop.Windows;
|
||||||
|
using osu.Game.IO;
|
||||||
|
|
||||||
namespace osu.Desktop
|
namespace osu.Desktop
|
||||||
{
|
{
|
||||||
@ -32,7 +33,7 @@ namespace osu.Desktop
|
|||||||
noVersionOverlay = args?.Any(a => a == "--no-version-overlay") ?? false;
|
noVersionOverlay = args?.Any(a => a == "--no-version-overlay") ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Storage GetStorageForStableInstall()
|
public override StableStorage GetStorageForStableInstall()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -40,7 +41,7 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
string stablePath = getStableInstallPath();
|
string stablePath = getStableInstallPath();
|
||||||
if (!string.IsNullOrEmpty(stablePath))
|
if (!string.IsNullOrEmpty(stablePath))
|
||||||
return new DesktopStorage(stablePath, desktopHost);
|
return new StableStorage(stablePath, desktopHost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
@ -64,7 +64,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected override string[] HashableFileTypes => new[] { ".osu" };
|
protected override string[] HashableFileTypes => new[] { ".osu" };
|
||||||
|
|
||||||
protected override string ImportFromStablePath => "Songs";
|
protected override string ImportFromStablePath => ".";
|
||||||
|
|
||||||
|
protected override Storage PrepareStableStorage(StableStorage stableStorage) => stableStorage.GetSongStorage();
|
||||||
|
|
||||||
private readonly RulesetStore rulesets;
|
private readonly RulesetStore rulesets;
|
||||||
private readonly BeatmapStore beatmaps;
|
private readonly BeatmapStore beatmaps;
|
||||||
|
@ -625,7 +625,7 @@ namespace osu.Game.Database
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set a storage with access to an osu-stable install for import purposes.
|
/// Set a storage with access to an osu-stable install for import purposes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<Storage> GetStableStorage { private get; set; }
|
public Func<StableStorage> GetStableStorage { private get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Denotes whether an osu-stable installation is present to perform automated imports from.
|
/// Denotes whether an osu-stable installation is present to perform automated imports from.
|
||||||
@ -638,9 +638,10 @@ namespace osu.Game.Database
|
|||||||
protected virtual string ImportFromStablePath => null;
|
protected virtual string ImportFromStablePath => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Select paths to import from stable. Default implementation iterates all directories in <see cref="ImportFromStablePath"/>.
|
/// Select paths to import from stable where all paths should be absolute. Default implementation iterates all directories in <see cref="ImportFromStablePath"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual IEnumerable<string> GetStableImportPaths(Storage stableStoage) => stableStoage.GetDirectories(ImportFromStablePath);
|
protected virtual IEnumerable<string> GetStableImportPaths(Storage storage) => storage.GetDirectories(ImportFromStablePath)
|
||||||
|
.Select(path => storage.GetFullPath(path));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this specified path should be removed after successful import.
|
/// Whether this specified path should be removed after successful import.
|
||||||
@ -654,24 +655,33 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Task ImportFromStableAsync()
|
public Task ImportFromStableAsync()
|
||||||
{
|
{
|
||||||
var stable = GetStableStorage?.Invoke();
|
var stableStorage = GetStableStorage?.Invoke();
|
||||||
|
|
||||||
if (stable == null)
|
if (stableStorage == null)
|
||||||
{
|
{
|
||||||
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
|
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stable.ExistsDirectory(ImportFromStablePath))
|
var storage = PrepareStableStorage(stableStorage);
|
||||||
|
|
||||||
|
if (!storage.ExistsDirectory(ImportFromStablePath))
|
||||||
{
|
{
|
||||||
// This handles situations like when the user does not have a Skins folder
|
// 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);
|
Logger.Log($"No {ImportFromStablePath} folder available in osu!stable installation", LoggingTarget.Information, LogLevel.Error);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.Run(async () => await Import(GetStableImportPaths(GetStableStorage()).Select(f => stable.GetFullPath(f)).ToArray()));
|
return Task.Run(async () => await Import(GetStableImportPaths(storage).ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Run any required traversal operations on the stable storage location before performing operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stableStorage">The stable storage.</param>
|
||||||
|
/// <returns>The usable storage. Return the unchanged <paramref name="stableStorage"/> if no traversal is required.</returns>
|
||||||
|
protected virtual Storage PrepareStableStorage(StableStorage stableStorage) => stableStorage;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
62
osu.Game/IO/StableStorage.cs
Normal file
62
osu.Game/IO/StableStorage.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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 osu.Framework.Platform;
|
||||||
|
|
||||||
|
namespace osu.Game.IO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A storage pointing to an osu-stable installation.
|
||||||
|
/// Provides methods for handling installations with a custom Song folder location.
|
||||||
|
/// </summary>
|
||||||
|
public class StableStorage : DesktopStorage
|
||||||
|
{
|
||||||
|
private const string stable_default_songs_path = "Songs";
|
||||||
|
|
||||||
|
private readonly DesktopGameHost host;
|
||||||
|
private readonly Lazy<string> songsPath;
|
||||||
|
|
||||||
|
public StableStorage(string path, DesktopGameHost host)
|
||||||
|
: base(path, host)
|
||||||
|
{
|
||||||
|
this.host = host;
|
||||||
|
|
||||||
|
songsPath = new Lazy<string>(locateSongsDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="Storage"/> pointing to the osu-stable Songs directory.
|
||||||
|
/// </summary>
|
||||||
|
public Storage GetSongStorage() => new DesktopStorage(songsPath.Value, host);
|
||||||
|
|
||||||
|
private string locateSongsDirectory()
|
||||||
|
{
|
||||||
|
var configFile = GetFiles(".", $"osu!.{Environment.UserName}.cfg").SingleOrDefault();
|
||||||
|
|
||||||
|
if (configFile != null)
|
||||||
|
{
|
||||||
|
using (var stream = GetStream(configFile))
|
||||||
|
using (var textReader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
string line;
|
||||||
|
|
||||||
|
while ((line = textReader.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (!line.StartsWith("BeatmapDirectory", StringComparison.OrdinalIgnoreCase)) continue;
|
||||||
|
|
||||||
|
var customDirectory = line.Split('=').LastOrDefault()?.Trim();
|
||||||
|
if (customDirectory != null && Path.IsPathFullyQualified(customDirectory))
|
||||||
|
return customDirectory;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetFullPath(stable_default_songs_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,6 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Collections;
|
using osu.Game.Collections;
|
||||||
@ -52,6 +51,7 @@ using osu.Game.Updater;
|
|||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.IO;
|
||||||
|
|
||||||
namespace osu.Game
|
namespace osu.Game
|
||||||
{
|
{
|
||||||
@ -88,7 +88,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
protected SentryLogger SentryLogger;
|
protected SentryLogger SentryLogger;
|
||||||
|
|
||||||
public virtual Storage GetStorageForStableInstall() => null;
|
public virtual StableStorage GetStorageForStableInstall() => null;
|
||||||
|
|
||||||
public float ToolbarOffset => (Toolbar?.Position.Y ?? 0) + (Toolbar?.DrawHeight ?? 0);
|
public float ToolbarOffset => (Toolbar?.Position.Y ?? 0) + (Toolbar?.DrawHeight ?? 0);
|
||||||
|
|
||||||
|
@ -71,8 +71,9 @@ namespace osu.Game.Scoring
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<string> GetStableImportPaths(Storage stableStorage)
|
protected override IEnumerable<string> GetStableImportPaths(Storage storage)
|
||||||
=> stableStorage.GetFiles(ImportFromStablePath).Where(p => HandledExtensions.Any(ext => Path.GetExtension(p)?.Equals(ext, StringComparison.OrdinalIgnoreCase) ?? false));
|
=> storage.GetFiles(ImportFromStablePath).Where(p => HandledExtensions.Any(ext => Path.GetExtension(p)?.Equals(ext, StringComparison.OrdinalIgnoreCase) ?? false))
|
||||||
|
.Select(path => storage.GetFullPath(path));
|
||||||
|
|
||||||
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);
|
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user