mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 21:47:25 +08:00
Merge pull request #1075 from peppy/import-from-stable-part-two
Tidy up osu-stable import process
This commit is contained in:
commit
d72a479d9d
@ -1 +1 @@
|
||||
Subproject commit 2204764944ff693e857649253547054cc91764a0
|
||||
Subproject commit 96daf2053a8a19fe221fef2557674ca5bee808fb
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Game;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
@ -11,6 +12,7 @@ using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Screens.Menu;
|
||||
|
||||
@ -30,6 +32,58 @@ namespace osu.Desktop
|
||||
};
|
||||
}
|
||||
|
||||
public override Storage GetStorageForStableInstall()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new StableStorage();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method of accessing an osu-stable install in a controlled fashion.
|
||||
/// </summary>
|
||||
private class StableStorage : DesktopStorage
|
||||
{
|
||||
protected override string LocateBasePath()
|
||||
{
|
||||
Func<string, bool> checkExists = p => Directory.Exists(Path.Combine(p, "Songs"));
|
||||
|
||||
string stableInstallPath;
|
||||
|
||||
try
|
||||
{
|
||||
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
|
||||
stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(String.Empty).ToString().Split('"')[1].Replace("osu!.exe", "");
|
||||
|
||||
if (checkExists(stableInstallPath))
|
||||
return stableInstallPath;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
|
||||
if (checkExists(stableInstallPath))
|
||||
return stableInstallPath;
|
||||
|
||||
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu");
|
||||
if (checkExists(stableInstallPath))
|
||||
return stableInstallPath;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public StableStorage()
|
||||
: base(string.Empty)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
@ -47,6 +47,8 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
private readonly FileStore files;
|
||||
|
||||
private readonly SQLiteConnection connection;
|
||||
|
||||
private readonly RulesetStore rulesets;
|
||||
|
||||
private readonly BeatmapStore beatmaps;
|
||||
@ -59,6 +61,11 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public Action<Notification> PostNotification { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set a storage with access to an osu-stable install for import purposes.
|
||||
/// </summary>
|
||||
public Func<Storage> GetStableStorage { private get; set; }
|
||||
|
||||
public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null)
|
||||
{
|
||||
beatmaps = new BeatmapStore(connection);
|
||||
@ -67,6 +74,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
this.storage = storage;
|
||||
this.files = files;
|
||||
this.connection = connection;
|
||||
this.rulesets = rulesets;
|
||||
|
||||
if (importHost != null)
|
||||
@ -136,13 +144,13 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="archiveReader">The beatmap to be imported.</param>
|
||||
public BeatmapSetInfo Import(ArchiveReader archiveReader)
|
||||
{
|
||||
BeatmapSetInfo set = null;
|
||||
|
||||
// let's only allow one concurrent import at a time for now.
|
||||
lock (importLock)
|
||||
{
|
||||
BeatmapSetInfo set = importToStorage(archiveReader);
|
||||
Import(set);
|
||||
return set;
|
||||
}
|
||||
connection.RunInTransaction(() => Import(set = importToStorage(archiveReader)));
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -169,7 +177,7 @@ namespace osu.Game.Beatmaps
|
||||
if (!beatmaps.Delete(beatmapSet)) return;
|
||||
|
||||
if (!beatmapSet.Protected)
|
||||
files.Dereference(beatmapSet.Files.Select(f => f.FileInfo));
|
||||
files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -183,7 +191,7 @@ namespace osu.Game.Beatmaps
|
||||
if (!beatmaps.Undelete(beatmapSet)) return;
|
||||
|
||||
if (!beatmapSet.Protected)
|
||||
files.Reference(beatmapSet.Files.Select(f => f.FileInfo));
|
||||
files.Reference(beatmapSet.Files.Select(f => f.FileInfo).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -451,19 +459,20 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 void ImportFromStable()
|
||||
{
|
||||
string stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!", "Songs");
|
||||
if (!Directory.Exists(stableInstallPath))
|
||||
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu", "Songs");
|
||||
var stable = GetStableStorage?.Invoke();
|
||||
|
||||
if (!Directory.Exists(stableInstallPath))
|
||||
if (stable == null)
|
||||
{
|
||||
Logger.Log("Couldn't find an osu!stable installation!", LoggingTarget.Information, LogLevel.Error);
|
||||
Logger.Log("No osu!stable installation available!", LoggingTarget.Information, LogLevel.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Import(Directory.GetDirectories(stableInstallPath));
|
||||
Import(stable.GetDirectories("Songs"));
|
||||
}
|
||||
|
||||
public void DeleteAll()
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Database;
|
||||
using SQLite.Net;
|
||||
using SQLiteNetExtensions.Extensions;
|
||||
@ -130,23 +129,11 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
private void cleanupPendingDeletions()
|
||||
{
|
||||
foreach (var b in QueryAndPopulate<BeatmapSetInfo>(b => b.DeletePending && !b.Protected))
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// many-to-many join table entries are not automatically tidied.
|
||||
Connection.Table<BeatmapSetFileInfo>().Delete(f => f.BeatmapSetInfoID == b.ID);
|
||||
foreach (var b in QueryAndPopulate<BeatmapSetInfo>(b => b.DeletePending && !b.Protected))
|
||||
Connection.Delete(b, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, $@"Could not delete beatmap {b}");
|
||||
}
|
||||
}
|
||||
|
||||
//this is required because sqlite migrations don't work, initially inserting nulls into this field.
|
||||
//see https://github.com/praeclarum/sqlite-net/issues/326
|
||||
Connection.Query<BeatmapSetInfo>("UPDATE BeatmapSetInfo SET DeletePending = 0 WHERE DeletePending IS NULL");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Database
|
||||
{
|
||||
var storeName = GetType().Name;
|
||||
|
||||
var reportedVersion = Connection.Table<StoreVersion>().FirstOrDefault(s => s.StoreName == storeName) ?? new StoreVersion
|
||||
var reportedVersion = Connection.Table<StoreVersion>().Where(s => s.StoreName == storeName).FirstOrDefault() ?? new StoreVersion
|
||||
{
|
||||
StoreName = storeName,
|
||||
Version = 0
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions;
|
||||
@ -83,10 +82,9 @@ namespace osu.Game.IO
|
||||
{
|
||||
string hash = data.ComputeSHA2Hash();
|
||||
|
||||
var info = new FileInfo { Hash = hash };
|
||||
|
||||
var existing = Connection.Table<FileInfo>().FirstOrDefault(f => f.Hash == info.Hash);
|
||||
var existing = Connection.Table<FileInfo>().Where(f => f.Hash == hash).FirstOrDefault();
|
||||
|
||||
var info = existing ?? new FileInfo { Hash = hash };
|
||||
if (existing != null)
|
||||
{
|
||||
info = existing;
|
||||
@ -106,11 +104,11 @@ namespace osu.Game.IO
|
||||
Connection.Insert(info);
|
||||
}
|
||||
|
||||
Reference(new[] { info });
|
||||
Reference(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
public void Reference(IEnumerable<FileInfo> files)
|
||||
public void Reference(params FileInfo[] files)
|
||||
{
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
@ -125,7 +123,7 @@ namespace osu.Game.IO
|
||||
});
|
||||
}
|
||||
|
||||
public void Dereference(IEnumerable<FileInfo> files)
|
||||
public void Dereference(params FileInfo[] files)
|
||||
{
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
@ -142,18 +140,21 @@ namespace osu.Game.IO
|
||||
|
||||
private void deletePending()
|
||||
{
|
||||
foreach (var f in QueryAndPopulate<FileInfo>(f => f.ReferenceCount < 1))
|
||||
Connection.RunInTransaction(() =>
|
||||
{
|
||||
try
|
||||
foreach (var f in Query<FileInfo>(f => f.ReferenceCount < 1))
|
||||
{
|
||||
Connection.Delete(f);
|
||||
Storage.Delete(Path.Combine(prefix, f.StoragePath));
|
||||
try
|
||||
{
|
||||
Storage.Delete(Path.Combine(prefix, f.StoragePath));
|
||||
Connection.Delete(f);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, $@"Could not delete beatmap {f}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, $@"Could not delete beatmap {f}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ using osu.Game.Screens.Menu;
|
||||
using OpenTK;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -47,6 +48,8 @@ namespace osu.Game
|
||||
|
||||
private UserProfileOverlay userProfile;
|
||||
|
||||
public virtual Storage GetStorageForStableInstall() => null;
|
||||
|
||||
private Intro intro
|
||||
{
|
||||
get
|
||||
@ -151,6 +154,7 @@ namespace osu.Game
|
||||
|
||||
// hook up notifications to components.
|
||||
BeatmapManager.PostNotification = n => notificationOverlay?.Post(n);
|
||||
BeatmapManager.GetStableStorage = GetStorageForStableInstall;
|
||||
|
||||
AddRange(new Drawable[] {
|
||||
new VolumeControlReceptor
|
||||
|
@ -62,7 +62,7 @@ namespace osu.Game.Rulesets
|
||||
{
|
||||
var us = createRulesetInfo(r);
|
||||
|
||||
var existing = Query<RulesetInfo>().FirstOrDefault(ri => ri.InstantiationInfo == us.InstantiationInfo);
|
||||
var existing = Query<RulesetInfo>().Where(ri => ri.InstantiationInfo == us.InstantiationInfo).FirstOrDefault();
|
||||
|
||||
if (existing == null)
|
||||
Connection.Insert(us);
|
||||
|
@ -115,7 +115,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToAny/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToCount/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToFirst/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToFirstOrDefault/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToFirstOrDefault/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToLast/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToLastOrDefault/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleCallToSingle/@EntryIndexedValue">WARNING</s:String>
|
||||
|
Loading…
Reference in New Issue
Block a user