1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 01:27:29 +08:00

Implement collection import

This commit is contained in:
smoogipoo 2020-09-03 00:08:33 +09:00
parent 39c304d008
commit a56f9d6770
4 changed files with 99 additions and 41 deletions

View File

@ -4,8 +4,10 @@
using System;
using System.Collections.Generic;
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.Containers;
@ -25,12 +27,13 @@ namespace osu.Game.Collections
private const string database_name = "collection.db";
public readonly BindableList<BeatmapCollection> Collections = new BindableList<BeatmapCollection>();
public bool SupportsImportFromStable => RuntimeInfo.IsDesktop;
[Resolved]
private GameHost host { get; set; }
public IBindableList<BeatmapCollection> Collections => collections;
private readonly BindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>();
[Resolved]
private BeatmapManager beatmaps { get; set; }
@ -40,12 +43,12 @@ namespace osu.Game.Collections
if (host.Storage.Exists(database_name))
{
using (var stream = host.Storage.GetStream(database_name))
collections.AddRange(readCollection(stream));
importCollections(readCollections(stream));
}
foreach (var c in collections)
foreach (var c in Collections)
c.Changed += backgroundSave;
collections.CollectionChanged += (_, __) => backgroundSave();
Collections.CollectionChanged += (_, __) => backgroundSave();
}
/// <summary>
@ -56,26 +59,55 @@ namespace osu.Game.Collections
/// <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()
// {
// var stable = GetStableStorage?.Invoke();
//
// if (stable == null)
// {
// Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
// return Task.CompletedTask;
// }
//
// if (!stable.ExistsDirectory(database_name))
// {
// // This handles situations like when the user does not have a Skins folder
// Logger.Log($"No {database_name} folder available in osu!stable installation", LoggingTarget.Information, LogLevel.Error);
// return Task.CompletedTask;
// }
//
// return Task.Run(async () => await Import(GetStableImportPaths(GetStableStorage()).Select(f => stable.GetFullPath(f)).ToArray()));
// }
private List<BeatmapCollection> readCollection(Stream stream)
public Task ImportFromStableAsync()
{
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))
{
// 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);
return Task.CompletedTask;
}
return Task.Run(() =>
{
var storage = GetStableStorage();
if (storage.Exists(database_name))
{
using (var stream = storage.GetStream(database_name))
{
var collection = readCollections(stream);
Schedule(() => importCollections(collection));
}
}
});
}
private void importCollections(List<BeatmapCollection> newCollections)
{
foreach (var newCol in newCollections)
{
var existing = Collections.FirstOrDefault(c => c.Name == newCol.Name);
if (existing == null)
Collections.Add(existing = new BeatmapCollection { Name = newCol.Name });
foreach (var newBeatmap in newCol.Beatmaps)
{
if (!existing.Beatmaps.Contains(newBeatmap))
existing.Beatmaps.Add(newBeatmap);
}
}
}
private List<BeatmapCollection> readCollections(Stream stream)
{
var result = new List<BeatmapCollection>();
@ -147,9 +179,9 @@ namespace osu.Game.Collections
using (var sw = new SerializationWriter(host.Storage.GetStream(database_name, FileAccess.Write)))
{
sw.Write(database_version);
sw.Write(collections.Count);
sw.Write(Collections.Count);
foreach (var c in collections)
foreach (var c in Collections)
{
sw.Write(c.Name);
sw.Write(c.Beatmaps.Count);

View File

@ -549,6 +549,8 @@ namespace osu.Game
ScoreManager.GetStableStorage = GetStorageForStableInstall;
ScoreManager.PresentImport = items => PresentScore(items.First());
CollectionManager.GetStableStorage = GetStorageForStableInstall;
Container logoContainer;
BackButton.Receptor receptor;

View File

@ -225,9 +225,8 @@ namespace osu.Game
dependencies.Cache(difficultyManager);
AddInternal(difficultyManager);
var collectionManager = new CollectionManager();
dependencies.Cache(collectionManager);
AddInternal(collectionManager);
dependencies.Cache(CollectionManager = new CollectionManager());
AddInternal(CollectionManager);
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore));
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory));

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Graphics.UserInterface;
using osu.Game.Scoring;
using osu.Game.Skinning;
@ -19,6 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
private TriangleButton importBeatmapsButton;
private TriangleButton importScoresButton;
private TriangleButton importSkinsButton;
private TriangleButton importCollectionsButton;
private TriangleButton deleteBeatmapsButton;
private TriangleButton deleteScoresButton;
private TriangleButton deleteSkinsButton;
@ -26,7 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
private TriangleButton undeleteButton;
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, DialogOverlay dialogOverlay)
private void load(BeatmapManager beatmaps, ScoreManager scores, SkinManager skins, CollectionManager collections, DialogOverlay dialogOverlay)
{
if (beatmaps.SupportsImportFromStable)
{
@ -93,9 +95,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
});
}
AddRange(new Drawable[]
{
deleteSkinsButton = new DangerousSettingsButton
Add(deleteSkinsButton = new DangerousSettingsButton
{
Text = "Delete ALL skins",
Action = () =>
@ -106,7 +106,32 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Task.Run(() => skins.Delete(skins.GetAllUserSkins())).ContinueWith(t => Schedule(() => deleteSkinsButton.Enabled.Value = true));
}));
}
},
});
if (collections.SupportsImportFromStable)
{
Add(importCollectionsButton = new SettingsButton
{
Text = "Import collections from stable",
Action = () =>
{
importCollectionsButton.Enabled.Value = false;
collections.ImportFromStableAsync().ContinueWith(t => Schedule(() => importCollectionsButton.Enabled.Value = true));
}
});
}
Add(new DangerousSettingsButton
{
Text = "Delete ALL collections",
Action = () =>
{
dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() => collections.Collections.Clear()));
}
});
AddRange(new Drawable[]
{
restoreButton = new SettingsButton
{
Text = "Restore all hidden difficulties",